Rails 5 bulk-update - ruby-on-rails

What I need to do is something like this:
users.update_all(number: some_specific_number_different_for_each_user)
Is there a better way of doing it other than iterating through users and updating each one separately? Even if I enclose it in transaction, it seems very inefficient...
Or is there a way to just save all records once I adjust the value, something like:
users.each_with_index { |u,i| u.number = i }
users.save_all
Any ideas?

Not unless the value to be updated can be set by the SQL function.
See(EDIT2)
update_all with a method

Related

Fill in unfilled properties with other model

I have an ActiveRecord model #new_profile that has some, but not all of its properties filled in. I have another model #default_profile that has a bunch of values I want to copy over, but only if the properties from the first are not filled in. Is there a built in way to do this besides a block like...
#new_profile.name ||= #default_profile.name
#new_profile.address ||= #default_profile.address
# etc.
This might work
#new_profile.update_attributes!(#default_profile.attributes.merge(#new_profile.attributes))
The problem with this, is that if the attribute is in #new_profile, but it is nil, the merge might leave the value set as nil. You might need to do the following.
new_profile_attrs = #new_profile.attributes.reject{ |key,value| !value }
#new_profile.update_attributes!(#default_profile.attributes.merge(new_profile_attrs))
#new_profile.update_attributes(#default_profile.attributes.merge(#new_profile.attributes))
You could try something like
#new_profile.attributes = #new_profile.attributes.reverse_merge #default_profile.attributes
If you need to copy ALL the attributes (except id of course):
#new_profile.attributes.each{|k,v| #new_profile[k] ||= #default_profile[k] if k != 'id'}
Things like update_attributes won't allow you to copy attr_protected-attributes. This thing should.

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.

How to get table column value?

I write follow code to get one record from the table webeehs:
webeehs_result = Webeeh.find(:all, :conditions=>["webeeh_project_id=#{project_id}"])
Then I want to get one column value from this record, how could I do?
For example, the column name is webeeh_date.
first of all, never EVER write code like that. Building your own conditions as pure strings can leave you vulnerable to SQL injection exploits. If you must do conditions, then do it like this:
:conditions => ["webeeh_project_id = ?", project_id]
if you have a Project model, you should rename the webeeh_project_id column from your Webeeh model into project_id and have an association in your Project model like has_many :webeehs
Then, you won't need to call that find anymore, just do a p = Project.find(id) and then p.webeehs will return the webeehs you need.
the result will be an array which you can iterate through. And to get your webeeh.webeeh_date member, just call it like this:
result.each do |webeeh|
date = webeeh.webeeh_date
end
webeehs_result = Webeeh.findwebeeh_dates
is enough to get all columnn values.
For a different method and performance issues check the following: http://www.stopdropandrew.com/2010/01/28/finding-ids-fast-with-active-record.html
webeeh_result will usually be an array of results for the database.
You can iterate throughit using
webeehs_result.each do |webeeh|
# use "webeeh.webeeh_date" to access the column_name or do whatever you want with it.
end

How to add up the value of a field in a rails find result

I do:
#deals = Deal.find(:all)
I use #deals for a number of things. Every deal has a value field (how much money the deal is worth). I want to know the combined value of all deals. I have this now:
#deals.each { |deal| #total_value += deal.value }
But I'm hoping and guessing ActiveRecords have a better way to do this? Is there?
Try following:-
#deals_value = Deal.sum(:value)
Thanks....
Assuming that you want to keep Deal.find(:all), and you want to use #deals to find the sum without a loop, try the following
#deals.sum(&:value)

Random jokes in a skit (activerecord)

I am working on populating my database with test data using populate.rake:
Repertoire.includes(:jokes).each do |r|
#jokes = r.jokes
Skit.populate 8..12 do |skit|
skit.joke_id = #jokes[rand(#jokes.count)].id
end
end
This is giving me a RuntimeError: Called id for nil.
How can I populate a skit with random jokes?
sort_by {rand} should sort your array of jokes.
Or, there is also doing an .order("rand()/random()") (depending on your db) in your Repertoire query and putting a limit on the query.
Not sure if this will fix your problem but Ruby has a rand method for arrays so you should be able to call #jokes.rand.id instead. Seems like that would simplify things and maybe even fix your error.

Resources