【问题标题】:Ruby on Rails save on model has_many to has_many doesn't trigger on buildRuby on Rails 保存模型 has_many 到 has_many 不会在构建时触发
【发布时间】:2019-02-09 23:54:29
【问题描述】:

我们有这个模型叫做“Cliente”(cliente.rb):

class Cliente < ApplicationRecord
    has_many :clientes_hardwares
    has_many :alertas_clientes
    has_many :sucursales
    has_many :alertas,   through: :alertas_clientes
    has_many :hardwares, through: :clientes_hardwares
end

SQL 表:

和模型“Alerta”(alerta.rb):

class Alerta < ApplicationRecord
    has_many :alertas_clientes
    has_many :clientes, through: :alertas_clientes
end

SQL 表:

然后我们创建了一个连接表。

 class CreateJoinTableClientesAlertas < ActiveRecord::Migration[5.2]
  def change
    create_join_table :clientes, :alertas do |t|
      # t.index [:cliente_id, :alerta_id]
      # t.index [:alerta_id, :cliente_id]
    end
  end
end

SQL 表名为“alertas_clientes”,其结构非常简单

模型是文件(alertas_cliente.rb):

class AlertasCliente < ApplicationRecord
    belongs_to :cliente
    belongs_to :alerta
end

我们想将关系保存在表格上,但控制台没有显示实际错误。

 def savenoti
        begin
         @cliente = Cliente.find(6)
         @cliente.alertas_clientes.build(
            :alerta => Alerta.find(1)
         )
         @cliente.save
        rescue => exception
            puts exception.message
            flash[:alert] = 'Error al enviar alerta.'
            redirect_to action: 'index'
        end
    end

但控制台显示:

Processing by AlertasController#sendnoti as HTML
  Cliente Load (0.3ms)  SELECT  `clientes`.* FROM `clientes` WHERE `clientes`.`id` = 6 LIMIT 1
  ↳ app/controllers/alertas_controller.rb:37
  Alerta Load (0.2ms)  SELECT  `alerta`.* FROM `alerta` WHERE `alerta`.`id` = 1 LIMIT 1
  ↳ app/controllers/alertas_controller.rb:39
   (0.1ms)  BEGIN
  ↳ app/controllers/alertas_controller.rb:41
   (0.1ms)  ROLLBACK
  ↳ app/controllers/alertas_controller.rb:41
wrong number of arguments (given 1, expected 0)

我错过了什么吗?

提前问候。

【问题讨论】:

  • 你能展示alertas_controller.rb的相关部分吗?特别是第 39 行和第 41 行的函数?看起来第 41 行的任何内容都是导致您的错误的原因。如果您在上面的代码中已经有了这些行,您能指出它们是哪些行吗?你也可以在你的控制器中添加logger.debug "value of foo is:#{@foo}" 在给你错误的行之前,并检查你的控制台日志,看看它是否试图保存你认为它正在保存的东西。它表示您正在为不期望的方法提供参数。
  • 感谢@Beartech 的回复,问题是字段名称是一个保留字

标签: ruby-on-rails ruby activerecord


【解决方案1】:

我已经知道真正发生了什么,问题是名称字段,所有关系都很好,但问题是模型 "Alerta" 有一个名为 "send" 的字段 这显然是 ruby​​ 的保留字。我改成 "send" 一切正常。

我知道这很奇怪,但如果 R​​ails 能显示这种类型的错误那就太好了。

【讨论】:

  • 它很难知道您何时使用保留字,因为它只是认为您以错误的方式使用它,哈哈,如果这有意义的话。 ? 我把它放在手边rubymagic.org/posts/ruby-and-rails-reserved-words
  • 也许在迁移时验证所有的单词 xD,那是很多东西
【解决方案2】:

查看错误显示的查询,您似乎在savenoti 内部调用Alerta.find(1) 时没有创建Alerta

假设您还没有创建Alerta,但您已经保存了客户端,您可以这样做:

def savenoti
  begin
   @cliente = Cliente.find(6)
   alerta = Alerta.new # or a different builder if you have any info to save
   @cliente.alertas.create(alerta) //this will create and save the `AlertasCliente` instance.
  rescue => exception
      puts exception.message
      flash[:alert] = 'Error al enviar alerta.'
      redirect_to action: 'index'
  end
end

如果不是这种情况,并且您已经将 Alerta 保存到数据库中,请按照 @Beartech 的要求将代码包含在第 39 行和第 41 行中。

无论如何,我都会使用普通的.alerts,因为它更清晰,这就是在模型上声明through: :alertas_clientes 的全部想法。如here 所述,还有更多方法可以为many_to_many 关联创建新记录。

【讨论】:

  • 感谢@moondaisy 的回复,问题是字段名称是一个保留字
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
相关资源
最近更新 更多