简体   繁体   中英

Can this Ruby on Rails code be optimized or improved at all?

The code:

user = ... #pretend it has a value :)
instances = Array.new
Product.all.each do |product|
    productInstance = ProductInstance.new
    productInstance.user = user
    productInstance.product = product
    instances.push(productInstance)
end

Product and ProductInstance are both Rails models. Is a for-each loop on Product.all going to be slow? Just wondering if there is a better way of doing this...

Never iterate on your whole collection at one time.

Maybe this will work fine on your development box, and maybe on you fresh production.

But when your application gets popular and your DB will have serious amount of records, you will get time and memory problems with your code.

Use for example http://apidock.com/rails/ActiveRecord/Batches/ClassMethods/find_in_batches and learn how garbage collection works http://timetobleed.com/garbage-collection-slides-from-la-ruby-conference/

Product.find_in_batches do |products|
  products.each do |product|
    productInstance = ProductInstance.new
    productInstance.user = user
    productInstance.product = product
    instances.push(productInstance)  
  end
end

I'd only change each to map (it's more idiomatic).

instances = Product.all.map do |product|
    productInstance = ProductInstance.new
    productInstance.user = user
    productInstance.product = product
    productInstance
end

Somthing like this should work.

instances = Product.all.map do |product|
    productInstance = ProductInstance.new(:user => user,:product => product)
end

or even

instances = Product.all.map do |product|
    ProductInstance.new(:user => user,:product => product)
end

For Mass assignment restriction you can try something like

instances = Product.all.map do |product|
    ProductInstance.new {|instance| instance.user = user;instance.product = product}
end

first in your ProductInstance model add

attr_accessible :user, :product 

and then

instances = Product.all.map {|product| ProductInstance.create(:user => user, :product => product)}

should work.

也可以这样做

 instances = Product.all.map {|product| ProductInstance.new(:user => user, :product => product)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM