Reputation: 1985
My question is twofold... Primarily, I am trying to figure out how to ask >
or <
when filtering this query. You can see at the end I have .where(:created_at > 2.months.ago)
and that is improper syntax, but I'm not sure the correct way to call something similar.
Secondly, this is a bit of a long string and is going to get longer as the are more conditions I have to factor in. Is there a cleaner way of building this, or is a long string of conditions like this pretty standard?
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
Thanks.
Upvotes: 0
Views: 1438
Reputation: 34072
Unfortunately you've hit a sore point in the ActiveRecord querying api. There is no standard, out of the box way to do this. You can do date ranges very easily, but <
and >
have no easy path. However Arel, the underlying SQL engine, can do this very easily. You could write a simple scope to handle it thusly:
scope :created_after, lambda {|date| where arel_table[:created_at].gt(date) }
And you could refactor this easily to take a column, or gt
versus lt
, etc.
Other people have solved this problem already, however, and you could take advantage of their work. One example is MetaWhere, which adds a bunch of syntactic sugar to your queries. For example, using it you might write:
Article.where(:title.matches => 'Hello%', :created_at.gt => 3.days.ago)
On #2, scopes do tend to get long. You might look into the gem has_scope, which helps to alleviate this by defining scopes on the controller in an analogous way to how they are defined on the model. An example from the site:
# 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
Upvotes: 4
Reputation: 3826
where(["created_at > ?", 2.months.ago])
for your first question.Upvotes: 2