Rails控制器中调用的方法出现了未定义的类方法错误。

3

我的Rails已经有些生疏了,我正在为自己找不出一个可能太基础而看不到问题的解决方法而苦恼。

我有一个表单,它可以去到我的控制器的create操作。当我保存时,我需要同时更新另一个表中的一些项目,并且我想将它们全部包装在一个事务中。我认为最好是把事务放在模型中。当我这样做并尝试调用create操作时,它会出现错误,告诉我该类别没有此方法。

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

模型 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

工具模型与所需方法
def transfer_equipment(location,ids)
  ids.each do |id|
    Tool.find(id).update(location: location)
  end
end

我原以为调用类方法会允许我在@equip_swap实例上执行该方法。但是当我尝试提交表单并创建新记录时,它告诉我Class...没有trans_equip_and_save方法。显然有些地方我没有注意到,请求帮助!

2个回答

8

方法以 self 开头表示调用类方法,不带 self 表示调用实例方法。让我举个例子。

Class method
def self.class_method
  # do some stuff
end

Instance method
def instance_method
  # do some stuff 
en

使用类方法进行调用
ModelName.class_method

使用实例方法调用

@instance_variable.instance_method

在你的代码中,将你的方法更改为实例方法。

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

现在使用实例变量@equip_swap.trans_equip_and_save调用此方法。

编辑:

如果您正在使用模型名称调用transfer_equipment,则在方法名称前添加self,我的意思是将其设置为类方法,如下所示

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

我从这行代码 Tool.transfer_equipment(self.to_vehicle, self.items_moved) 中得到了一个新的错误 undefined method 'transfer_equipment' for #<Class:0x007ff28ff9af18>。我需要改变这些代码中的 self,以显式地调用实例吗? - Beartech
将其更改为 def self.transfer_equipment(location,ids) - Sajin

2
请注意以下两点:
首先有两种不同的方法,即“类方法”和“实例方法”。
类方法:类方法直接在类上定义,并使用“def self.method”进行定义。
用法:Class.method 实例方法:实例方法定义在类的对象上,且没有self。
用法:object = Class.new(), def method ==> object.method 因此,在您的情况下,将有两个更改:
1)您调用了@equip_swap.trans_equip_and_save
由于@equip_swap是一个对象,根据第二点,您应该有一个没有self的实例方法。
def trans_equip_and_save
  EquipSwap.transaction do
    Tool.transfer_equipment(self.to_vehicle, self.items_moved)
    self.save
  end
end

2) Tool.transfer_equipment 这个函数需要使用 class name 来调用。所以,根据第一点,应该使用 self 来调用。

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

@Beartech,请检查我的答案,你需要做两个更改。已添加解释。 - Sravan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接