##resportstroller的未定义方法`scope':0xde24d2c> </reportscontroller:0xde24d2c>

时间:2014-02-06 18:53:11

标签: ruby-on-rails ruby activerecord rails-activerecord

我正在尝试编写动态查询来搜索已发送的邮件。我已经写好了这样的东西,我知道它有更多的错误。

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>

3 个答案:

答案 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将其转换为范围。