I’m working through the RailsTutorial but making an “Announcements” webapp for the middle school I teach at (tweaking the given Twitter clone).
When users create an announcement, they use check boxes to determine which grades it should be displayed to (1-3 grades could be true). This is working correctly, with me storing grades as booleans.
create_table "announcements", :force => true do |t|
t.string "content"
t.integer "user_id"
t.boolean "grade_6"
t.boolean "grade_7"
t.boolean "grade_8"
t.date "start_date"
t.date "end_date"
t.datetime "created_at"
t.datetime "updated_at"
end
My users also have a grade field, which is an integer. I want to use this to make each user’s home page show the announcements for their grade.
Example: An 8th grade teacher has grade = 8. When they log in, their home page should only show announcements which have grade_8 = TRUE.
Example: An principal has grade = 0. When they log in, their home page should show all announcements.
I’m struggling with how to translate the integer user.grade value into boolean flags for pulling announcements from the model.
The code I’m writing is working, but incredibly clunky. Please help me make something more elegant! I’m not tied to this db model, if you have a better idea. (In fact, I really don’t like this db model as I’m hardcoding the number of grades in a number of locations).
# Code to pull announcements for the home page
def feed
case grade
when 6
grade_6
...
else
grade_all
end
end
# Example function to pull announcements for a grade
def grade_6
Announcement.where("grade_6 = ? AND start_date >= ? AND end_date <= ?",
TRUE, Date.current, Date.current)
the correct way to set this type of relationship up would be to use a many-to-many relationship via has_many through:
then your migrations will be:
so, now you can simply find your grade then call announcements to filter:
so, that’s the correct way to do it from a modeling perspective. there are other considerations to this refactor as you will have to make significant changes to your forms and controllers to support this paradigm, but this will also allow for much greater flexibility and robustness if you decide you want to attach other types of objects to a grade besides just announcements. this railscast demonstrates how to manage more than one model through a single form using nested form elements, this will help you keep the look and feel the same after you apply the changes to your models. I hope this helps, let me know if you need more help doing this, it’ll be a bit of work, but well worth it in the end.