Rails ActiveRecord update_all array of ids - ruby-on-rails

I have an ActiveRecord Model called Animal.
Animal has id and client_id.
In my app have an array called #selectedanimals that contains the id's of the animals I want to update such as: #selectedanimals: ["6", "14", "5"].
I have the value of a new client_id for these animals like #newclient.id and I want to update all of these Animal records with the new client_id.
What I have now is:
Animal.update_all({:client_id => #transferclient.id}, {:id => #selecteanimals})
I know this is not 100% correct because it is having a problem with :id.
I get an error like this:
Called id for nil, which would mistakenly be 8 -- if you really wanted the id of nil, use object_id
Forgive my ignorance but this is my first time using update_all and I don't see any examples where you pass it an array of the ids of the records you want to update so any help would be appreciated much.
EDIT:
Apparently the #transferclient.id was not properly defined. That was my problem.
Thanks all.

I am new to Ruby so I don't know if there's been some recent change in the API but Danpe's answer as well as the initial suggestion that actually worked according to the asker, didn't work for me. They both raised a syntax error.
The solution that worked for me and is actually proposed in the API documentation is this:
Animal.where(:id => #selectedanimals).update_all(:client_id => #transferclient.id)

You need to check if id is inside that array:
Animal.update_all({:client_id => #transferclient.id}, {"id IN (?)" , #selecteanimals})

Related

If condition on RABL

I have two attributes in my relation - flyer and flyer_url. I want to put an if condition which assigns either flyer or flyer_url to flyer_image_url depending on which is not null. All the records have either of them set to null. I've tried the following code but it is only assigning flyer_url to flyer_image_url even when it is null:
attribute :flyer => :flyer_image_url
attribute :flyer_url => :flyer_image_url, :if => lambda { |flyer_url| !flyer_url.nil? }
Please help!
Thanks!!
Thanks to Nathan Esquenazi - the creator of RABL, I finally got the answer.
This is a limitation (although somewhat intentional) of RABL, for a given key name “flyer_image_url” there should only ever be a single statement associated with it. Trying to have two statements associated with a single key is what is causing the confusion here.
He suggests using a single node instead with custom logic: https://github.com/nesquena/rabl#custom-nodes
node :flyer_image_url do |object|
object.flyer_url.nil? ? object.flyer : object.flyer_url
# This is just ruby, put whatever you want that ends up as a string
end
That worked like a charm! Hope this answer finds somebody!

How can I get all the records in a table where any value of an associated table is in a given array?

I think if I had a better idea how to word this question, I would have been able to find an answer already... Anyways, I have a table called Vendors that has a many-to-many relationship with a table called Basins. I would like to be able to retrieve all the vendors that have at least one basin in an array of basins that is passed in as input.
So if I had three vendors like:
vendor1.basins = [Basin.first, Basin.second]
vendor2.basins = [Basin.second, Basin.third]
vendor3.basins = [Basin.third, Basin.fourth]
And I wanted to get all the vendors containing anything from [Basin.first, Basin.fourth], I would get both vendor1 and vendor3. If the array was [Basin.first, Basin.second], I would get both vendor1 and vendor2. I thought select might be the way to go here, but everything I've tried has been flagrantly wrong.
Thanks in advance.
I am assuming you are using Rails >= v4.0.0.
You can get vendors like:
Vendor.joins(:basins).where(basins: { id: [Basin.first.id, Basin.fourth.id] })
I hope this will help you.
You can add scope to Vendor model:
scope :foo, ->(basins_arr){ joins(:basins).
where(basins: { id: basins_arr.collect(&:id)})

Delete by Id in mongoid

Is there any one command in Mongoid to delete an object using id?
Something like,
ClassName.delete(:id)
Currently i dont see anything like that and im using,
obj = ClassName.find(:id)
obj.delete
Can it be any better?
Another Way
ClassName.any_in(:_id => ["id1", "id2"]).destroy_all
You can do something like the following:
ClassName.delete_all(conditions: { _id: BSON::ObjectId("whatevertheidis")})
You need the underscore in _id or it won't work.
Also, it may not matter, but destroy_all will run the model's callback methods while delete_all does not.

Rails: Getting column value from query

Seems like it should be able to look at a simple tutorial or find an aswer with a quick google, but I can't...
codes = PartnerCode.find_by_sql "SELECT * from partner_codes where product = 'SPANMEX' and isused = 'false' limit 1"
I want the column named code, I want just the value. Tried everything what that seems logical. Driving me nuts because everything I find shows an example without referencing the actual values returned
So what is the object returned? Array, hash, ActiveRecord? Thanks in advance.
For Rails 4+ (and a bit earlier I think), use pluck:
Partner.where(conditions).pluck :code
> ["code1", "code2", "code3"]
map is inefficient as it will select all columns first and also won't be able to optimise the query.
You need this one
Partner.where( conditions ).map(&:code)
is shorthand for
Partner.where( conditions ).map{|p| p.code}
PS
if you are often run into such case you will like this gem valium by ernie
it gives you pretty way to get values without instantiating activerecord object like
Partner.where( conditions ).value_of :code
UPDATED:
if you need access some attribute and after that update record
save instance first in some variable:
instance=Partner.where( conditions ).first
then you may access attributes like instance.code and update some attribute
instance.update_attribute || instance.update_attributes
check documentation at api.rubyonrails.org for details

Why "Object#id will be deprecated; use Object#object_id" when accessing AR record ID? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Rails primary key and object id
I am baffled as to why I cannot refer an object's attributes; hope someone can help...
I need to build a hash that will associate Marker.marker_name with it's id from the database, which are already stored (the record id will serve as a foreign key in another table).
So, first I retrieve the Marker record via this named scope:
class Marker < ActiveRecord::Base
named_scope :by_name, lambda { |marker_name|
{:conditions => ["marker_name = ?", marker_name]}}
which is called from my Uploads model, like this (marker_name has the value "Amelogenin"):
this_marker = Marker.by_name(marker_name)
I know this worked, because when I Use the debugger, I can see what is in this_marker, which looks like:
(rdb:2) y this_marker
!ruby/object:Marker attributes:
created_at: 2011-03-14 22:21:27.244885
updated_at: 2011-03-14 22:21:27.244885
id: "11"
marker_name: Amelogenin attributes_cache: {}
Yet, I cannot assign the record id in my hash, like this:
$markers[marker_name] = this_marker.id
I cannot seem to refer directly to the id in this way; because, even in the debugger, I get this error:
(rdb:2) p this_marker.id
(__DELEGATION__):2: warning: Object#id will be deprecated; use Object#object_id
Is there some kind of different Ruby syntax I need to be using or what? How can I associate the marker_name with its record id?
Thanks in advance....
This Marker.by_name(marker_name) returns an array of makers. You should write:
this_marker = Marker.by_name(marker_name).first
This kind of error happens when one calls id method on non ActiveRecord object. So make sure this_marker is AR object instance.
this_marker = Marker.by_name(marker_name) are you sure this returns one Marker object? There is no call to all or first.
That is a very confusing error message, (and I bet it's a fairly common problem too).
Marker.by_name(marker_name) does not return an active record object, but a scope, which does not have an active record id, only the Object#id method, which is deprecated (and gone in Ruby 1.9.2).
Scopes are lazy - they won't access the database until you try to use them (or print them, as in your case).
Try Marker.by_name(marker_name).first

Resources