按模型方法过滤而不是db列Rails

时间:2015-08-17 17:57:23

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

我试图在我的rails app中构建一个过滤器,它使用url params并根据我模型中的方法返回记录(根据几个不同的标准返回true或false)而不是直接检查db 。我有一些问题。

这是我模型中的代码

def action_required?
    true unless (self.nap_correct? && self.claimed? && self.duplicates == "")
end

在我看来,我有一个使用params过滤结果的链接。这是代码

<%= link_to "All Messages", url_for(:action_required => true) %>

在我的控制器中

if params[:action_required].blank?
  @citations = @client.citations.paginate(:page => params[:page], :per_page => 50).order("id desc")
else
  @citations = @client.citations.where(:action_required => true).paginate(:page =>[:page], :per_page => 50).order("id desc")
end

现在它给了我这个错误

SQLite3::SQLException: no such column: citations.action_required: SELECT "citations".* FROM "citations" WHERE "citations"."client_id" = ? AND "citations"."action_required" = 't'

我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

首先,您不需要编写true unless...,只需执行

def action_required?
  self.nap_correct? && self.claimed? && self.duplicates == ""
end

然后将您的复杂条件转换为scope

scope :action_required, ->(){
  self.where(nap_correct: true, claimed: true, duplicated: '')
}

然后你可以使用范围:

@citations = @client.citations.action_required.paginate(:page =>[:page], :per_page => 50).order(id: :desc)

如果您的#nap_correct?claimed?方法也是复杂的Ruby方法,并且不仅仅是模型中的字段,那么您还需要将它们提取到SQL中(例如创建scopes)。

有一种更简单的方法:将where替换为.select(&:action_required) - 将使用Ruby Array方法选择记录(因此选择是在Ruby中完成的,而不是在数据库中 - 因此会慢一些) 。而且你也必须手动处理分页,因为paginate期望ActiveRecord::Relation可以运行查询,而不是Ruby数组。