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" }
Другие вопросы по тегам