Rails ActiveRecord查询

时间:2011-09-10 20:50:40

标签: ruby-on-rails-3 activerecord

我的问题有两个......主要是,我试图弄清楚在过滤此查询时如何询问><。你可以看到最后我有.where(:created_at > 2.months.ago),这是不正确的语法,但我不确定调用类似的东西的正确方法。

其次,这是一个很长的字符串,并且会变得更长,因为我需要考虑更多的条件。是否有更简洁的方法来构建它,或者是一个很长的条件,像这样的标准?

class PhotosController < ApplicationController
  def showcase
    @photos = Photo.order(params[:sort] || 'random()').search(params[:search]).paginate(:per_page => 12, :page => params[:page]).where(:created_at > 2.months.ago)
  end

感谢。

2 个答案:

答案 0 :(得分:4)

不幸的是,你在ActiveRecord查询api时遇到了痛点。没有标准的,开箱即用的方式来做到这一点。您可以非常轻松地完成日期范围,但<>没有简单的路径。但是,底层SQL引擎Arel可以非常轻松地完成这项工作。你可以编写一个简单的范围来处理它:

scope :created_after, lambda {|date| where arel_table[:created_at].gt(date) }

您可以轻松地重构此列,或gtlt等。

然而,其他人已经解决了这个问题,你可以利用他们的工作。一个例子是MetaWhere,它为你的查询添加了一堆语法糖。例如,使用它你可以写:

Article.where(:title.matches => 'Hello%', :created_at.gt => 3.days.ago)

在#2上,范围确实会变长。您可以查看gem has_scope,这有助于通过在控制器上定义范围以及在模型上定义它们的方式来缓解这种情况。该网站的一个例子:

# The model
# Note it's using old Rails 2 named_scope, but Rails 3 scope works just as well.
class Graduation < ActiveRecord::Base
  named_scope :featured, :conditions => { :featured => true }
  named_scope :by_degree, proc {|degree| { :conditions => { :degree => degree } } }
end

# The controller
class GraduationsController < ApplicationController
  has_scope :featured, :type => :boolean
  has_scope :by_degree

  def index
    @graduations = apply_scopes(Graduation).all
  end
end

答案 1 :(得分:2)

  • 第一个问题可以where(["created_at > ?", 2.months.ago])
  • 对于您的第二个问题,有几种解决方案:
    • 您可以使用范围将条件嵌入其中,然后将它们合并。
    • 您可以在多行中断行。
    • 如果你有一个大屏幕并且你不与任何其他人合作,你可以保持这样。