Rails Filtering Best-Practices
I have a web app that has the fo开发者_开发知识库llowing models: Shifts, Years, Checkouts, Sales and Visitors.
A Shift has_many Checkouts, Sales, Visitors A Year has_many Shifts
Checkouts, Sales and Visitors belong_to Shift Shifts belong_to Year
In my app, I want to have many different years present, although only ONE is active at any given time. When I display Shifts, for example, I only want Shifts from the active year to be displayed. That's easy enough.
What I'm having a real hard time with is writing a query to get all of the checkouts from the active year. Is there a simple way to go about doing this? The active year is actually set in a session variable called session[:current_year_id]. I thought the best way to go about doing it would be to do something like:
@checkouts = Shift.where('year_id = ?',session[:current_year_id]).checkouts
But that's not working for me. What do I need to change to get that to work?
Note that checkouts, sales and visitors DO NOT have their own year_id. They have a year_id through the shift that they belong to.
Resolved:
I upvoted all the answers, since all helped. I used the for_year lambda expression. I've upvoted all the answers.
The final answer was to use:
Shift.for_year(session[:current_year_id]).collect{ |shift| shift.checkouts }
You can create a scope in Shift model that takes current year as parameter:
class Shift < ActiveRecord::Base
has_many :checkouts
scope :for_year, lambda { |current_year_id| where('year_id = ?', current_year_id) }
end
and in the controller, you can get the checkouts for current year by chaining to the scope:
Shift.for_year(session[:current_year_id]).map(&:checkouts)
Using .where
returns a relation, so there are two possible answers based on your intention.
If you want to find the checkouts belonging to the first shift, do:
@checkouts = Shift.where('year_id = ?',session[:current_year_id]).first.checkouts
If you want all checkouts for all shifts, do:
@checkouts = Shift.where('year_id = ?',session[:current_year_id]).collect{|shift| shift.checkouts}
You could try:
Shift.find_all_by_year_id(session[:current_year_id])
This assumes current_year_id
is in the session.
I have had problems with using .where
, which I fixed by using a dynamic finder.
精彩评论