RoR Take atrributes from ActiveRecord::Relation - ruby-on-rails

I'm a novice at RoR. Tell me please how to take attributes from ActiveRecord::Relation? For Example I write:
#user = User.where(code: 123)
next I want to take attribute id
id = #user.id
but this method is not working. Thanks in advance

When use .where it gives you an active record relation so you can't find id directly on it because it's a relation not a single model object.
Fix:
You can do
#user = User.where(code: 123).first
OR
You can use dynamic finders
#user = User.find_by_code(123)

If you want to find single user with code == 123, you can use find_by method, like this:
#user = User.find_by(code: 123)
It returns User instance, so you can call id method on it.
EDIT: If you use Rails prior to 4.x version, you can use dynamic find_by_code finder:
#user = User.find_by_code(123)

You are using where clause it returns array. Use it like :
#user = User.where(code: 123).first
Above is not right way for query. So you can also write your code to find user like :
#user = User.find_by_code(123)
With above two ways you get single object and you can find any attribute from it. #user.id etc

I guess you are missing first, where returns an array of objects, so you need to use first to get the object out of array
Do this
#user = User.where(code: 123).first
id = #user.id

Related

why does Rails think Model attribute is a method?

This is a custom rake task file, if that makes a difference.
I want to pull all user_id's from Pupil, and apply them to get the User.id for all pupils.
It happily prints out line 2 with correct user_id, but then considers user_id a 'method' and breaks on line 3. Why? Where is my mistake?
course_pupils = Pupil.where(course_id: study.course_id)
course_pupils.map { |a| puts a.user_id }
pupils = User.where(id: course_pupils.user_id )
course_pupils is still a relation when you are calling it in line 3. Line 2 is non destructive (and if it was, it would turn it into an array of nils because puts returns nil).
You need to do:
pupils = User.where(id: course_pupils.pluck(:user_id) )
Or something like that
You are doing it wrong, you cannot call an instance method user_id on a collection, try this instead
user_ids = Pupil.where(course_id: study.course_id).pluck(:user_id)
pupils = User.where(id: user_ids )
Hope that helps!

Fetch ActiveRecord query result as an array of hashes with chosen attributes

The model User has first, last and login as attributes. It also has a method called name that joins first and last.
What I want is to iterate through the Users records and create an array of hashes with the attributes I want. Like so:
results = []
User.all.map do |user|
record = {}
record["login"] = user.login
record["name"] = user.name
results << record
end
Is there a cleaner way in Ruby to do this?
Trying to map over User.all is going to cause performance issues (later, if not now). To avoid instantiating all User objects, you can use pluck to get the data directly out of the DB and then map it.
results = User.all.pluck(:login, :first, :last).map do |login, first, last|
{ 'login' => login, 'name' => first << last }
end
Instantiating all the users is going to be problematic. Even the as_json relation method is going to do that. It may even be a problem using this method, depending on how many users there are.
Also, this assumes that User#name really just does first + last. If it's different, you can change the logic in the block.
You can use ActiveRecord::QueryMethods#select and ActiveRecord::Relation#as_json:
User.select(:login, '(first || last) as name').as_json(except: :id)
I would write:
results = User.all.map { |u| { login: u.login, name: u.name } }
The poorly named and poorly documented method ActiveRecord::Result#to_hash does what you want, I think.
User.select(:login, :name).to_hash
Poorly named because it does in fact return an array of Hash, which seems pretty poor form for a method named to_hash.

Find_by returns first record

When using find_by and just supplying an id param, find_by returns the first entry in the table.
E.g.
#article = Article.find_by(params[:article_id])
returns article with id = 1 while using find gives me the article with id = :article_id
Can somebody explain why find_by returns the record with the first id?
Using the find method, you can retrieve the object corresponding to the specified primary key that matches any supplied options.
so this is correct syntax
#article = Article.find(params[:article_id])
while The find_by method finds the first record matching some conditions
so you should write
#article = Article.find_by(id:params[:article_id])
source:http://guides.rubyonrails.org/active_record_querying.html
You can also try #article = Article.find_by(:id => params[:article_id])

Ruby - how to create dynamic model attributes?

I have an array with model attributes (these model attributes are columns in DB table). I am trying to iterate through this array and automatically create a record which I would like to save to DB table, something like this:
columns.each_with_index do |c, i|
user.c = data[i]
puts user.c
end
user is model.
But if I try the snippet above, I get
undefined method `c=' for #<User:0x007f8164d1bb80>
I've tried also
columns.each_with_index do |c, i|
user."#{c}" = data[i]
puts user."#{c}"
end
But this doesn't work as well.
Data in columns array are taken from form that sends user, so I want to save only data that he send me, but I still cannot figure it out...
I would like to ask you for help... thank you in advance!
user.send("#{c}=".to_sym, data[i])
Also, you can access the attributes as a hash.
user.attributes[c] = data[i]
The best thing would probably be to build a hash and to use update_attributes:
mydata = {}
columns.each_with_index{|c, i| mydata[c] = data[i]}
user.update_attributes(mydata)
this way you retain the protections provided by attr_accessible.
If this is actually in a controller, you can just make use of some basic rails conventions and build the User record like this:
#user = User.new(params[:user])
if #user.save
# do something
else
# render the form again
end
Although you can set the values using send, I agree with #DaveS that you probably want to protect yourself via attr_accessibles. If your planning to use Rails 4, here's a good overview.

Finding a particular attribute's value from a model in Rails

I'm trying to find the value of a particular model's attribute in rails. Here's what my code in the User controller's 'create' method looks like:
#user = User.find(1, :select => :money)
existing_money = #user
puts "#{existing_money}"
In my Heroku logs I'll see a variant of the following output instead of the :money integer for that particular user (with :id 1)
#<User:0x00000004e7cbc0>
Any thoughts? Thanks!
#user = User.find(1, :select => :money)
You are setting the #user instance variable with an object that has only one value, namely the money value. For now, all this does is save you a few bytes, by leaving off things like id, email, and any other columns you have in that table. It does however still return an object with attributes, the only difference is your object has only one attribute to call.
existing_money = #user
Given that #user is still an object with a single attribute, you now save this object in the existing_money local variable. What you probably want to do is *only store the money attribute in this variable`.
So you'd need this:
existing_money = #user.money
puts "#{existing_money}"
After the above change, this puts statement should return the attribute value, not the object encapsulating the attribute.
As existing_money is just the object you are seeing the object's ID.
As you want the money attribute you have to reference that too.
puts "#{existing_money.money}"

Resources