I have a search method written for my model Link.
I’ve been able to called this method without error until implementing voting. For example, these all work:
Link.search(params[:search])
current_user.links.search(params[:search])
current_account.links.search(params[:search])
The following does not work:
@links = current_user.votes.collect {|vote| vote.voteable}
@favorites = @links.search(params[:search])
and return this error:
undefined method `search' for #<Array:0x00000006919ac8>
I’ve done some testing, to see if my class is wrong, in the console:
links = user.votes.map {|vote| vote.voteable}
links.class
=> Array
links.first.class
=> Link
This should be no different than my working examples:
user.links.class
=> Array
user.links.first.class
=> Link
I thought maybe the error was from me calling search on an array and not a link. But in previous examples I’m also calling it on an array.
I’m using vote_fu to handle the voting thus the vote/voteable.
The search function or scope that you have defined is defined on the Link object and is usable in Link relations, but it is not defined on a simple array, which is what is getting returned from the first collect example. Here is a simple distinction:
In your first example,
Link.search(params[:search]), you are performing the equivalent ofUser.search.all, and User is a scoped ActiveRecord relation/object, which means it can continue to be combined with other scopes, like where, limit and group. In the second example,@links = current_user.votes.collect {|vote| vote.voteable}, collect is acting on such a relation and is returning a simple array which can no longer be acted upon with these scoped functions. The second example is like doingUser.all.search.It’s confusing because both of these examples resolve to an Array eventually, but the difference is what is happening before that resolution to an Array, and when you are actually calling the search function. To get around this you’ll have to actually call the search scope or function on an ActiveRecord object, like Link or an ActiveRecord Relation like
current_user.links, but you won’t be able to call it on a result. Just to clarify:When you call
.collectyou are implicitly calling.all, which breaks the scope chain. The following two commands are equivalent in that respect: