undefined method `where' for #<Group:0x8623338> - ruby-on-rails

I'm trying to find my group by ID and put a where on it(Title in this case. Dates in another case) But it throws the error undefined method where' for #<Group:0x8623338>
This is my query:
group = Group.find_by_id(params[:group_id]).where(:title => '%titel%')

This should work:
group = Group.where(title: '%title%').find_by_id(params[:group_id])
The reason you get this error is you can't call 'scope' methods on ActiveRecord::Base instance (which is returned by find_by_id method). Now, you call where on Group (which is ok) and then call find_by_id on relation returned by where.

Try this
group = Group.where("title like ? AND id =?", '%titel%', params[:group_id])

Related

lambda select map difference in rails 4

Servernode is Rails Model Class.
I found something strange to me when I try to use lambda.
aaa = lambda {|node| node.available="Available"}
Servernode.select(&:aaa)
=> It can return array of ModelObject which meets the condition
But, when I try to
bbb = lambda {|node| node if node.available="Available"}
Servernode.map(&:bbb)
NoMethodError: undefined method `map' for #<Class:0x000000067759b0>
The result is not what I expected and don't know why?
Thanks for help!
This is because select is an ActiveRecord::QueryObject method. I think you've confused it with the select method for Ruby Enumerable. The map method is only available for enumerables as well.

Why does this return no method error when trying ordering?

I'm using the gem called acts_as_follower(https://github.com/tcocca/acts_as_follower)
Here, I'm trying to fetch all the users who are following current_user.
then I want them ordered by the column called last_active_at
So I tried to code like this but it returned error.
How can I fix?
controller
#followed_users = current_user.followers.order('users.last_active_at DESC').limit(10)
Error Message
NoMethodError (undefined method `order' for #<Array:0x0000000ab3cf18>):
followers method return Array
and Array do not have any order method in ruby
Please look
From github:--
"book.followers # Returns an array of all the followers for that book, a collection of different object types (eg. type User or type Book)"
so you can try this
ASC:
current_user.followers.sort!{ |a,b| a.created_at <=> b.created_at }.take(10)
DESC:
current_user.followers.sort!{ |a,b| b.created_at <=> a.created_at }.take(10)
Arrays dont have any order method. You could do something like this
#followed_users = current_user.followers.sort_by{ |n| n.last_active_at }
Then when displaying in the view you can limit it to how many ever you want or do it from the controller (suggested way).
According to the readme#github followers takes an optional hash parameter of ActiveRecord options (:limit, :order, etc…)
So this should work:
#followed_users = current_user.followers(:order => 'users.last_active_at DESC', :limit => 10)

Rails 3 - NoMethodError: undefined method for nil:NilClass in each Iteration

I'm iterating over an array of instances of a Rails model. Here is my code:
product_details.each do |product_detail|
product_detail.label = Backend::ProductGroup.where(product_group_number: product_detail.product_group).first.label
end
The attribute 'label' from 'product_detail' isn't an attribute from my Rails ActiveRecord model. I added it with attr_accessor in my class definition. I did this, because I wanted to add this attribute dynamically, only when I need to do this. When I ran the code without the 'each' iteration in my rails console it works just fine. But when I execute the above code I get the following error message:
NoMethodError: undefined method 'label' for nil:NilClass
Did I do something obviously wrong?
Many thanks in advance.
You likely have several product_detail items that have no matching product_group. So calling .first on the empty collection returns nil. To get around the error, you can test if the product_group was found before proceeding:
product_details.each do |product_detail|
product_group = Backend::ProductGroup.where(product_group_number: product_detail.product_group).first
product_detail.label = product_group.label if product_group
end
You can also do this more efficiently like so:
group_labels = BackEnd::ProductGroup.
where(product_group_number: product_details.map(&:product_group)).
inject({}){|m, g| m[g.product_group_number] = g.label; m}
product_details.each do |product_detail|
product_detail.label = group_labels[product_detail.product_group]
end
This will result in a single database call to grab all related groups, and put the labels in a keyed hash for easy discovery and assignment.

Check for nil gives error

I have this line in my controller:
user = User.any_of({:user_name => login}, {:email => login})
if user.nil?
# ...
elsif user.legacy_password.nil?
And it creates this error:
undefined method `legacy_password' for []:Array
Why would this happen? the user object is supposed to be nil. At least that is what the debugger said.
I'm assuming your any_of method returns an array of results, not a single result. You probably want to add .first to the end of it, which will give you either a User record, or nil if any_of returned an empty array.
user = User.any_of({:user_name => login},{:email => login}).first
Looks like you are using mongoid (#any_of) and it's returning an array.
The error is because you are calling legacy_password on an array, but I assume it is defined on the User model.

Rails 3 - Undefined method on certain collections

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:
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>
In your first example, Link.search(params[:search]), you are performing the equivalent of User.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 doing User.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:
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
When you call .collect you are implicitly calling .all, which breaks the scope chain. The following two commands are equivalent in that respect:
#links = current_user.votes.collect {|vote| vote.voteable}
#links = current_user.votes.all.collect {|vote| vote.voteable}

Resources