Ruby on Rails:使用选项定义方法

时间:2009-12-09 15:30:45

标签: ruby-on-rails ruby

我正在寻找一个允许我传递选项的方法;类似的东西:

@user.tasks(:completed => true)

我认为这样的事情会在我的用户模型中起作用(但事实并非如此):

User.rb模型

  def tasks(options)
    tasks.find(:all, options)
  end

如何正确定义方法让我使用@ user.tasks(:completed => true)?

5 个答案:

答案 0 :(得分:6)

这基本上就是我的做法:

def tasks(options={})
  unless options[:something].blank? 
    # do stuff
  end
end

有一些不同的方法可以传递选项,但你肯定希望传递一个带有默认值的哈希值(这样你就可以调用没有选项的方法)。

在您的情况下,以下内容应解决您想要做的事情:

def tasks(options={})
  Task.find(:all, options[:conditions])
end

修改:然后将其命名为@thing.tasks( {:conditions => "blah"} )

我没有测试但是应该没问题

编辑2:但是像EmFi说这样做并不是最佳选择。请考虑使用关联。你可以去@thing.tasks.find(:all, :conditions => {blah})

答案 1 :(得分:5)

用户是否有has_many :tasks关联?这似乎就是你在这里所追求的。在这种情况下,Rails为您提供了查找程序,您可以像这样访问:

@user.tasks.find :all, :conditions => { :completed => true }

甚至更短:

@user.tasks.all :conditions => { :completed => true }

如果这不够简洁并且您总是想要使用特定条件,请尝试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

答案 2 :(得分:2)

为什么要将另一个模型上的find all与实例方法相关联?我可以理解它是否是一个关系,并且find需要根据调用记录查找选项。但是那里有ActiveRecord协会。

然后是ActiveRecord :: Base#all(options),它是Task.find(:all,options)的别名

让事情更简单:

class User < ActiveRecord::Base
  has_many :tasks
end

@user.tasks.all(:conditions => {:completed => true})

答案 3 :(得分:1)

你需要的是:

方法中的选项[:conditions]

答案 4 :(得分:0)

Activerecord提供了一个名为with_scope的方法,以便传递任何附加条件

@user.tasks(:completed => true)

您可以将任务方法定义为

def tasks(options={})
  with_scope :find => options
    User.all :order => 'id desc'
  end
end

这会将作为options参数传递的任何哈希与实际的find

合并

唯一需要注意的是,您需要稍微修改方法调用

@user.tasks(:conditions => {:completed => true})

或类似

@user.tasks(:select => 'username')

但如果用户和任务模型之间存在关联,那么我会在他的帖子中做到乔