Reputation: 4632
I'm looking to define a method that lets me pass options; something like:
@user.tasks(:completed => true)
I thought something like this would work in my user model (but it's not):
User.rb model
def tasks(options)
tasks.find(:all, options)
end
How would I define the method correctly to let me use @user.tasks(:completed => true)?
Upvotes: 3
Views: 7125
Reputation: 66436
This is basically how I'd do it:
def tasks(options={})
unless options[:something].blank?
# do stuff
end
end
There are some different ways to pass options, but you definitively want to pass a hash with a default value (so that you can call the method without options).
In your case the following should address what you want to do:
def tasks(options={})
Task.find(:all, options[:conditions])
end
Edit: and then call it @thing.tasks( {:conditions => "blah"} )
I haven't tested but it should be ok
Edit 2: But like EmFi said it's not optimal to do this. Consider using an association instead. You'll be able to go @thing.tasks.find(:all, :conditions => {blah})
Upvotes: 6
Reputation: 3696
Activerecord provides a method called with_scope, so to pass any additional conditions
@user.tasks(:completed => true)
you can define the task method as
def tasks(options={})
with_scope :find => options
User.all :order => 'id desc'
end
end
and this will merge any hash passed as options parameter with the actual find
The only caveat is you need to modify your method call slightly
@user.tasks(:conditions => {:completed => true})
or to something like
@user.tasks(:select => 'username')
But if there is an association between user and tasks model then I would do what Jordan has in his post
Upvotes: 0
Reputation: 23450
Why would you associate a find all on another model with an instance method? I could understand if it was a relation and the find required find options based on the calling record. But there's ActiveRecord Associations for that.
Then there's ActiveRecord::Base#all(options) which is an alias for Task.find(:all, options)
Together make things simpler:
class User < ActiveRecord::Base
has_many :tasks
end
@user.tasks.all(:conditions => {:completed => true})
Upvotes: 2
Reputation: 106027
Does User have a has_many :tasks
association? That seems to be what you're after here. In that case Rails provides finders for you, which you can access like this:
@user.tasks.find :all, :conditions => { :completed => true }
Or even shorter:
@user.tasks.all :conditions => { :completed => true }
If that's not terse enough and you always want to use a particular condition, try a named scope:
# In your Task model:
named_scope :completed, :conditions => { :completed => true }
# Then you can just call...
@some_user.tasks.completed # => Only completed Tasks for @some_user
Upvotes: 5