Kom*_*mbo 2 arrays activerecord ruby-on-rails ruby-on-rails-3
我有一个为我的模型Link编写的搜索方法.
在实施投票之前,我已经能够毫无错误地调用此方法.例如,这些都有效:
Link.search(params[:search])
current_user.links.search(params[:search])
current_account.links.search(params[:search])
Run Code Online (Sandbox Code Playgroud)
以下不起作用:
@links = current_user.votes.collect {|vote| vote.voteable}
@favorites = @links.search(params[:search])
Run Code Online (Sandbox Code Playgroud)
并返回此错误:
undefined method `search' for #<Array:0x00000006919ac8>
Run Code Online (Sandbox Code Playgroud)
我在控制台中做了一些测试,看看我的课程是否错误:
links = user.votes.map {|vote| vote.voteable}
links.class
=> Array
links.first.class
=> Link
Run Code Online (Sandbox Code Playgroud)
这应该与我的工作示例没有什么不同:
user.links.class
=> Array
user.links.first.class
=> Link
Run Code Online (Sandbox Code Playgroud)
我想也许错误来自于我在数组上调用搜索而不是链接.但在之前的例子中,我也在一个数组上调用它.
我使用vote_fu处理投票,从而投票/投票.
您定义的搜索功能或范围是在Link对象上定义的,可用于链接关系,但它没有在简单数组上定义,这是从第一个收集示例返回的内容.这是一个简单的区别:
class User
scope :search, lambda{ |name| where(name: name) }
end
User.search('Kombo').all # Returns an array of the SQL result run against the DB
User.all.search('Kombo') # NoMethodError: undefined method `search' for #<Array:0x000001079b15b0>
Run Code Online (Sandbox Code Playgroud)
在第一个示例中Link.search(params[:search]),您执行的是等效的User.search.all,并且User是一个作用域的ActiveRecord关系/对象,这意味着它可以继续与其他范围组合,例如where,limit和group.在第二个例子中@links = current_user.votes.collect {|vote| vote.voteable},collect正在对这样的关系起作用,并返回一个简单的数组,该数组不再能用这些范围的函数作用.第二个例子就像做User.all.search.
这是令人困惑的,因为这两个示例最终都解析为一个数组,但不同之处在于在解析数组之前发生的事情,以及当您实际调用搜索函数时.要解决这个问题,你必须实际调用ActiveRecord对象上的搜索范围或函数,比如Link或ActiveRecord Relation current_user.links,但是你无法在结果上调用它.只是为了澄清:
Link.search(params[:search]) # will work
Link.all.search(params[:search]) # will not work
current_user.links.search(params[:search]) # will work
current_user.links.all.search(params[:search]) # will not work
current_account.links.search(params[:search]) # will work
current_account.links.all.search(params[:search]) # will not work
Run Code Online (Sandbox Code Playgroud)
当你打电话时,.collect你是隐式调用.all,这打破了范围链.在这方面,以下两个命令是等效的:
@links = current_user.votes.collect {|vote| vote.voteable}
@links = current_user.votes.all.collect {|vote| vote.voteable}
Run Code Online (Sandbox Code Playgroud)