Beartech Beartech -4 years ago 103
Ruby Question

Undefined method error for class in Rails method called in controller

My Rails have gotten rather rusty and I'm driving myself crazy trying to figure out something that is probably so basic I can't see the forest for the trees.

I have a form that goes to the

create
action of my controller. When I save I need to also update some items from another table. I want to wrap it all in a transaction. I thought the preference was to put the transaction in the model. When I do that and try to call the
create
action it errors out telling me that there is no method for that class.

equip_swaps_controller.rb

def create
respond_to do |format|
@equip_swap = EquipSwap.new(equip_swap_params)
if @equip_swap.trans_equip_and_save
format.html { redirect_to @equip_swap, notice: 'Equipment transfer was successfully created.' }
else
format.html { render action: 'failure' }
end
end
end


Model equip_swap.rb

def self.trans_equip_and_save
EquipSwap.transaction do
Tool.transfer_equipment(self.to_vehicle, self.items_moved)
self.save
end
end


Tool model with needed method

def transfer_equipment(location,ids)
ids.each do |id|
Tool.find(id).update(location: location)
end
end


I thought that calling the class method would allow it to execute that method on my instance of the
EquipSwap
instance
@equip_swap
. When I try to submit the form and create the new record it tells me that there is no
trans_equip_and_save
method for
Class....
. There is something obvious that I'm missing. Help!

Answer Source

Method start with self its call class method and and without self its call instance method, let me give example

Class method
def self.class_method
  # do some stuff
end

Instance method
def instance_method
  # do some stuff 
en

Call class method using

ModelName.class_method

Call instance method using

@instance_variable.instance_method

In your code change your method to instance method

def trans_equip_and_save
 EquipSwap.transaction do
  Tool.transfer_equipment(self.to_vehicle, self.items_moved)
  self.save
 end
end

And now call this method using instance variable @equip_swap.trans_equip_and_save

Edit:

If you are calling transfer_equipment using model name then add self before method name, I mean make it class method like following

def self.transfer_equipment(location,ids)
  ids.each do |id|
    Tool.find(id).update(location: location)
  end
end
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download