2011-09-10 115 views
0

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

其次,这是一个很长的字符串,将会变得更长,因为我必须考虑更多的条件。是否有一个更清洁的方式来构建它,或者是像这样漂亮的一长串条件标准?

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
  • 您可以为where(["created_at > ?", 2.months.ago])做第一个问题。
  • 对于第二个问题,有几种解决方案:
    • 您可以使用作用域将条件嵌入它们中,然后将它们合并。
    • 您可以在多行中打破该行。
    • 如果你有一个大屏幕,你不与任何其他人一起工作,你可以保持这样。
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