我正在尝试编写动态查询来搜索已发送的邮件。我已经写好了这样的东西,我知道它有更多的错误。
def create
scope :before, lambda { |value| where('created_at <= (?)', value) if value }
scope :after, lambda { |value| where('created_at >= (?)', value) if value }
scope :from, lambda { |value| where('from LIKE (?)', value) if value }
scope :to, lambda { |value| where('to LIKE (?)', value) if value }
scope :with_message, lambda { |value| where('message LIKE (?)', value) if value }
@report = SentMessage.create_before(params[:report][:before])
.created_after(params[:report][:after])
.from(params[:report][:from])
.to(params[:report][:to])
.with_message(params[:report][:with_message])
.all.reverse
respond_with(@report)
end
我收到这样的错误;
undefined method `scope' for #<ReportsController:0xde24d2c>
提前谢谢。
改进代码后; 我现在正在接受这个;
undefined method `default_scoped?' for #<String:0xcfa2678>
改进的代码看起来像这样;
scope :created_before, lambda { |value| where("created_at <= (?)", value) if value }
scope :created_after, lambda { |value| where("created_at >= (?)", value) if value }
scope :sent_from, lambda { |value| where("from like (?)", "%#{value}%").to_sql if value }
scope :sent_to, lambda { |value| where("to like (?)", "%#{value}%").to_sql if value }
scope :with_message, lambda { |value| where("message like (?)", "%#{value}%").to_sql if value }
并且控制器操作如下所示;
def create
@report = SentMessage.created_before(params[:report][:before])
.created_after(params[:report][:after])
.sent_from(params[:report][:from])
.sent_to(params[:report][:to])
.with_message(params[:report][:message])
.all.reverse
respond_with(@report)
end
,新错误是
undefined method `default_scoped?' for #<String:0xd4c928c>
答案 0 :(得分:3)
范围属于它们的范围。这样您就可以在整个应用程序中重复使用它们。
请注意,范围名称是您定义的名称(:before
转换为SentMessage.before
而不是SentMessage.create_before
)
例如:
@user = User.valid
答案 1 :(得分:2)
范围是在不在控制器中的模型中创建的。 您可以从控制器中引用它们。 请参阅链接以获取示例:Rails Guides: ActiveRecord
答案 2 :(得分:2)
范围不适合这样的工具。范围是通用查询构建器,但它们看起来像是单个控制器。
我可能会从控制器中的私有查询构建器开始:
def messages_matching(query)
query ||= { }
# This can be generalized with some Hashes and iteration but there's
# little point to that when there are so few options.
msgs = SentMessage
msgs = msgs.where('created_at <= ?', query[:before ] ) if(query[:before ])
msgs = msgs.where('created_at >= ?', query[:after ] ) if(query[:after ])
msgs = msgs.where('from like ?', "%#{query[:from ]}%") if(query[:from ])
msgs = msgs.where('to like ?', "%#{query[:to ]}%") if(query[:to ])
msgs = msgs.where('message like ?', "%#{query[:with_message]}%") if(query[:with_message])
msgs.order('created_at desc') # Or whatever order you really want
end
然后:
def create
@report = messages_matching(params[:report])
respond_with @report
end
稍后,如果您发现自己一遍又一遍地使用这些代码段,请使用SentMessage
上的class methods将其转换为范围。