get model attribute dynamically in rails 3 - ruby-on-rails

How can I get the attribute from the model object dynamically? I have the attribute of the User object as string:
u = User.find(1)
Can I do something like u.get("user_id")

You could try using the ActiveRecord model instance like a hash.
u = User.find(1)
name = u[:name]
field = "first_name"
first_name = u[field]

Yet another approach:
attr = :first_name
#user.read_attribute attr

Try this
user = User.find(1)
then something like this should do what you require
user.send('field_name')

Try this
u = User.find(1)
attr = "first_name"
u.send(attr)

Not sure if I totally understand your questions. Try something like:
User.find(1).name
if you mean you only want to fetch from DB specific attribute you can do:
User.find(1,:select => :name)

Related

Cannot Define Attribute in Create method Rails

In rails 4.2.4, I can successfully execute this line of code.
Model.Create!(name: "Bob")
In Rails 4.2.5, this does nothing and leaves me with a null field in the database. To get past this, I must do something like this...
s = Model.Create!()
s.name = "Bob"
s.save!
Does anyone know why the first method doesn't work? Has rails been updated to something different? I haven't been able to find a solution for this. Thanks in advance.
Difference Between Model.create() and Model.new()
Model.create() It will create and save empty columns DB, if its not "validated".
Model.new() It will create empty table but not saves it in DB. Until will not be saved.
Example:
u = User.new
u.first_name = 'Joe'
u.last_name = 'Doe'
u.save #this saves DB.
Here is good Examples

RoR Take atrributes from ActiveRecord::Relation

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

Rails - find by with two fields using OR instead of AND?

I am familiar with doing a find on two fields:
user = User.find_by_username_and_email(params[:username], params[:email])
However, I would like to retrieve one record where the username OR email equals the same field. Something like:
user = User.find_by_username_or_email(params[:text])
Which I know doesn't work. Is this possible? Any help is a appreciated.
Just to expand on the answer by #xdazz, you can use the following syntax to allow searching any number of fields by the same value without having to repeat the value:
user = User.where('username = :text or email = :text', :text => params[:text]).first
Very useful when you come to search postal address fields, for example.
2.2.1 Placeholder Conditions
You could use .where :
user = User.where('username = ? or email = ?', params[:text], params[:text]).first

How can I select the minimummonths value?

In SQL I would do this:
SELECT minimummonths WHERE name = "gold"
I want to do the same in Ruby on Rails and have the following in the new section of my orders controller:
#plan = params[:plan]
#Payplanrow = Payplan.where(:name => #plan).minimummonths
I then try to display #payplanrow in my page using <%=#Payplanrow %> but it doesnt work. I get the error:
undefined method `minimummonths' for #<ActiveRecord::Relation:0x007fe30f870ec0>
I want to print the minimummonths value for the plan selected. There will only ever be one row of data corresponding to the #plan value.
I'm pretty new to Ruby on Rails so I'm just trying to get a pointer in the right direction. I looked everywhere but there doesn't seem to be an example of this.
The problem is Payplan.where(:name => #plan) is returning an array of Payplan objects. Assuming you are using Rails 3, you can read more about it in "Active Record Query Interface".
But, if you are certain that your query is returning only one record you could do:
#Payplanrow = Payplan.where(:name => #plan).first.try(:minimummonths)
The Rails way is to have a scope in your model:
class Payplan < ActiveRecord::Base
scope :by_name, lambda {|name|
{:conditions => {:name => name}}
}
end
#controller
#Payplanrow = Payplan.by_name(#plan).first.try(:minimummonths)
Although it's not really optimal, you can do:
#Payplanrow = Payplan.where(:name => #plan).first.minimummonths
You can use pluck to get only the minimummonths value :
minimummonths = Payplan.where(:name => #plan).pluck(:minimummonths).first
Instead of using where then first, it's better to use find when you are expecting a single record.
#Payplanrow = Payplan.find_by_name(#plan).try(:minimummonths)
That should be:
Payplan.where(:name => #plan).first.minimummonths

Rails: Find and use the id number from a diff controller

I want to extract the id number of a unique record, that resides in a different controller as an integer, so I can save it as part of a new record in a new controller.
I can't seem to get the id to shed it's 'Array' attribute.
I've been using this:
class MessagesController < ApplicationController
def incoming
a = Group.where("name = ?", name).map { |n| n.id }
group_number = a.id
puts "#{group_number} is the number!"
end
output is always [2] or [3] or whatever.
adding this doesn't seem to cure it
group_as_int = group_number.to_i
Lastly, the reason I'm doing all this is to save that group number as a new record in a third controller, like this:
Subscriber.create(:group_id => group_number, :active => "1")
or
Subscriber.create(:group_id => group_as_int, :active => "1")
Of course, the create balks when I try to pass an array into the create function.
Thoughts?
You are trying to put business logic into the controller.
Try to refactor your methods and put them into your models instead.
Beside that you get the number in the following way:
group = Group.where("name = ?", name).first
group_number = group.id if group.present?
You might want to try .first to get the integer out of the array.
I will try to explain from your code what you did wrong.
The first line:
matching_group_ids = Group.where("name = ?", name).map { |n| n.id }
You called it a, but i prefer more verbose names. matching_group_ids now holds an array of id's. To get the first value of this array, the easiest solution is to just write
group_number = matching_group_ids[0]
or, more readable:
group_number = matching_group_ids.first
Mind you: you should test that the returned array is not empty.
Hope this helps.

Resources