byCoder
byCoder

Reputation: 9184

Rails update related model data in update method

I have such code:

def update
    @oil = Oil.find(params[:id])
    @product_types = ProductType.all    
    if @oil.update_attributes(params[:oil])
      if @oil.other_products_cross_lists.update_attributes(:cross_value => @oil.model.to_s.gsub(/\s+/, "").upcase)
        redirect_to admin_oils_path
      end
    else
      render :layout => 'admin'
    end
  end

but when i run it i get:

undefined method `update_attributes' for #<ActiveRecord::Relation:0x007f7fb4cdc220>

and my other_products_cross_lists isn't updated... Also i try update_attribute and get the same error.

What i do wrong?

Also when i run my destroy method

def destroy
    @oil = Oil.find(params[:id])
    if @oil.destroy
      if @oil.other_products_cross_lists.destroy
        redirect_to admin_oils_path
      end
    else
      render :layout => 'admin'
    end
  end

other_products_cross_lists didn't destroy...

How can i solve this problem?

model:

class Oil < ActiveRecord::Base
  has_many :other_products_cross_lists, :foreign_key => 'main_id'

class OtherProductsCrossList < ActiveRecord::Base
  belongs_to :oil

Upvotes: 1

Views: 1630

Answers (2)

Martin M
Martin M

Reputation: 8638

as the error says other_products_cross_lists is a relation (I assume your model oil has_many other_products_cross_lists).

update_attribute is a method of an instance of a model, not a method of a relation.

I don't really understand, what you want to do with you update_attribute, but if user nested_attributes, then

@oil.update_attributes(params[:oil])

takes care of updating the relation.

Also, if you define your relation beween Oil and OtherProducts as dependend: :destroy Rails handles the removel of dependent records.

Upvotes: 0

Hassan Javeed
Hassan Javeed

Reputation: 464

other_products_cross_lists is an association on your Oil model. You cannot use update_attributes on an Array or ActiveRecord:Relation object.

What you should do is

@oil.other_products_cross_lists.each {|list| list.update_attributes(:cross_value => @oil.model.to_s.gsub(/\s+/, "").upcase)}

for destroying

you can use

@oil.other_products_cross_lists.delete_all

or

@oil.other_products_cross_lists.destroy_all

You should check out the difference between delete_all and destroy_all for clarity.

Upvotes: 2

Related Questions