update_attributes inside each rails - ruby-on-rails

I have array of data
array = [1,2,4,6]
and what i want it update my model like this
array.each do |a|
Mymodel.all.each do |mm|
mm.update_attributes(name: a)
end
end
but problem is when im trying to do this
update_attributes only with last a
at the end all objects have name 6
How can fix it?

because thats what you are doing, you are running each loop over the array but you are doing the same.
first iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 1)
end
second iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 2)
end
last iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 6)
end
so you just update every time the attribute name to the element in the array. and the last one is there to keep.
your logic is incorrect.

That's logical. For every element in the array you're updating all the model records. So first you're updating all your model entries with the first value in your array, being 1, then you're doing the same for very every model entry only with the value 2. Last value in your array is 6 so you're setting all the values in your model to name with the value 6.
I'm not sure what you're trying to accomplish but from your question I assume you want to update your model in order of your array. So something like this.
model_entries = Mymodel.all
array.each do |value, index|
model_entries[index].update_attributes(name: value)
end
That's one solution, but it seems to me that's something wrong with your base logic here. From where I stand this is certainly something you want to solve in a different way. I can't really go into detail here as I don't know enough about what it is you're trying to achieve

Related

Active record sum giving the wrong answer

Hi I'm working on a project and I have to get the sum of an attribute of a active record collection. So I used:
#total = #records.sum(:cost)
However this gives the wrong value, for example if I have:
#records.each{ |x| puts x.cost}
I get 118.80 and 108.00
but for #total I get 680.40, which obviously isn't the answer, however if I use:
#total = 0
#records.each{ |x| #total = #total + x.cost}
I get the right answer of 226.80
If anyone can help me understand what is going on here it would be greatly appreciated.
Be careful, as a record collection is an instance of ActiveRecord::Associations::CollectionProxy, not an Array. It means that if you call:
#object.collection.sum(:cost)
actually what gets called is this method: http://apidock.com/rails/v4.2.7/ActiveRecord/Calculations/sum
And it will call sum in the SQL database, so the result gets influenced by the parameters of the query, e.g. groups, joins, etc.
While if you want to use Array sum, as in here: http://apidock.com/rails/Enumerable/sum
You would have to make your object Array first, via to_a:
#object.collection.to_a.sum(&:cost)
try this:
pluck the values of attr cost into an array and aggregate their sum
#total = #records.pluck(:cost).sum

rails each loop with from to

In my controller i fetch 9 row's for object organizations.
#organizations = Organization.where(parent_id: 1).order(city_id: :asc, is_vip: :desc, title: :asc).limit(25).sample(9)
and then in view i must separate this 9 value's to 3 view loops, like first .each do if for row's 1-3, second for 4-6, third 6-9
and i try so:
- #organizations[0..2].each do |org|
...
- #organizations[3..5].each do |org|
...
- #organizations[6..8].each do |org|
...
but it seems that i do something wrong, but what exactly? and how to do it right?
Not sure why your data is duplicated. But you can use the following method for splitting the array into slices
you can use each_slice
#organization.each_slice(3) do |sliced_orgs|
end
Some documentation here
First I don't really get why you use .limit(25).sample(9), you could limit your results to 9 already. But maybe you have some use of the random factor introduced by sample? Strange.
Other than that,
#organizations[0..2].each do |org|
puts org
end
...
should work perfectly fine. If the data is repeated it is because you have multiple times the same entry in your model. sample(9) is taking random unique entries and #organizations[0..2] is a fixed range returning an array or nil. (Rubydoc : ary[range] → new_ary or nil)
In short, nothing wrong with the code but probably somewhere in your data/logic.

Can't get Array's count method to work with a block

I have a Rails app that contains a TeamSeason model class. This class has a has_one association with a Team model class, and a has_many association to another TeamSeason called opponents. I'm now trying to write a method that passes in a Team and determines whether any of its opponents are associated with that Team. The method I wrote looks something like this:
def plays?(against_team)
total = opponents.count {|opponent| opponent.team == against_team}
return (total > 0)
end
The count method should count the number of array elements that yield a true value with the block I specified. However, it appears that it is always returning the full length of the array. It's as if the block I specified always yields a true value, no matter what.
I added various puts calls to try and figure out where my logic is going wrong. Here's my observations:
When I add any puts calls inside the block next to the count method, I do not see any output for those statements. It appears that the contents of the block are never being executed
When I insert an additional loop using the opponents array's each method and a block, I can print the value of my array objects and confirm they are evaluate as I expect. I can even puts the value of opponent.team == against_team and verify that the block I wrote evaluates to false some of the time, as it should.
What am I missing here?
opponents is not a standard ruby Array - it's an ActiveRecord association proxy and behaves differently for certain methods. count will query the database for the number of opponents, and the block you are passing will not be evaluated. A simpler way to do what you want is like so:
def plays?(against_team)
opponents.joins(:team).where(teams: {id: against_team.id}).exists?
end
This will ask the database what you want, and avoid loading all opponents when you are only checking for a specific match. Alternatively, you can load the entire opponents list and use any?:
def plays?(against_team)
opponents.any?{|opponent| opponent.team == against_team.id}
end
Note that this will not only load all opponents, but it will load each opponent's team one at a time - resulting in an N+1 query (which leads to performance issues). You can avoid this by eager loading the associated team using includes():
opponents.includes(:team).any?{...}
The functionality which you are trying can be achieved using include? method.
Try:
def plays?(against_team)
opponents.collect(&:team).include?(against_team)
end

Looping Through two or more intance vars in Rails

In my view I have two instance variables (going to be more) that I want to display in one table. The first, #data, is an instance var of a model, someting like #data=RnFile.all.
The second is an array #result containing a value per data in #data calculated in the controller. Now in my view I want to display them next to each other, something like:
#data[0].atributes #result[0]
#data[1].atributes #result[1]
#data[2].atributes #result[2]
#data[3].atributes #result[3]
...
but I can't figure out how to iterate over both the arrays (and propably more to come).
Any suggestions anyone? Thanks
You can use Array#zip to do what you want:
#data.zip(#results).each do |data, result|
# use data and result as you need here
end

Rails 3 remove item from existing array without another sql call

So this below has always worked for me, but now I need to remove some of the items to get true cost and true sale price. I need to remove all items from this sum that has a parent_id of nil. How can I do this without making another sql query?
def total_price
# convert to array so it doesn't try to do sum on database directly
items.to_a.sum(&:full_price)
end
You can do
items.to_a.reject{|item|item.parent_id.nil?}.sum(&:full_price)
Use select/reject method on array.

Resources