Rails 3.2: цепочка лямбда-прицелов?
В моем приложении Rails 3.2.8 у меня есть несколько именованных областей, которые я хотел бы объединить в цепочку при некоторых обстоятельствах.
Так, например, у меня есть эти две области:
scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }
scope :in_date_range, lambda { |start_date, end_date| includes([:person, :pier_module]).where("(status_date >= ?) AND (status_date <= ?)", start_date, end_date) }
Я использую их отдельно, но я также хотел бы иметь возможность вызывать их вместе так:
WorkRequest.by_status("Accepted").in_date_range("2012-01-01", "2012-10-02")
Когда я пытаюсь это жалуется, что in_date_range не является методом Array.
Но у меня есть другая сфера,
scope :active, includes([:person, :pier_module]).where("status = 'New Request'")
и если я сделаю
WorkRequest.active.in_date_range("2012-01-01", "2012-10-02")
оно работает! По-видимому, активная область возвращает отношение, тогда как лямбда-области возвращают массивы и поэтому не могут быть связаны.
Я хотел бы знать, почему разница между простыми и лямбда-областями, как параметры влияют на это, и есть ли что-то, что я могу сделать, кроме написания комбинированной области, что я и сделал.
scope :by_status_in_date_range, lambda { |status, start_date, end_date| includes([:person, :pier_module]).where("(status = ?) AND (status_date >= ?) AND (status_date <= ?)", status, start_date, end_date) }
Работает, но не очень СУХОЙ (так как мне тоже нужны отдельные области) или Rails-ish. В поисках здесь и в других местах я видел похожие вопросы, но ни один из них, похоже, не относится к этой ситуации, где я пытаюсь связать две лямбды с параметрами.
1 ответ
Это происходит потому, что в вашей сфере
scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }
metods all
а также find_all_by_status
возвращается Array
вместо ActiveRecord::Relation
, Вы должны заменить его на where
например.
scope :by_status, lambda { |status| where(:status => status) unless status == "All" }