首页 > 解决方案 > Ruby 模型构造函数给出错误:传递的参数数量错误

问题描述

我在 macOS 上使用 Rails 6.0。我的班级定义如下:

class Asset < ApplicationRecord
  def initialize (symbol, name, type, listed_on, faceValue)
    @name=name
    @symbol=symbol
    @type=type
    @faceValue=faceValue
    @listed_on=listed_on
    p "Insde Constructor"
  end
end

我正在尝试从 Rails 控制台实例化它

在此处输入图像描述

我观察到的更奇怪的事情是,当我尝试使用不同数量的参数进行实例化时,我得到以下更改的响应 在此处输入图像描述

标签: ruby-on-railsruby

解决方案


不要乱用 ActiveRecord 的初始化方法。如您所见,坏事发生了。相反,用于attr_accessor添加非列字段。

class Asset < ApplicationRecord
  attr_accessor :symbol, :name, :type, :listed_on, :faceValue
end

这允许访问列和您的额外属性。例如,如果资产表具有列成本...

asset = Asset.new(
  cost: 12.34,   # set the cost column
  name: "Junk",
  type: :junk,
  listed_on: Time.current,
  faceValue: 0,
  symbol: :jnk
)

如果您真的需要搞乱初始化,请使用after_initialize 回调


如果 symbol、name、type、listed_on 和 faceValue 都是 assets 表的列,则什么也不做。ActiveRecord 会处理它。

class Asset < ApplicationRecord
end

asset = Asset.new(
  name: "Junk",
  type: :junk,
  listed_on: Time.current,
  faceValue: 0,
  symbol: :jnk
)

如果没有资产表,则根本不要从 ActiveRecord 继承。

class Asset
  def initialize (symbol, name, type, listed_on, faceValue)
    @name=name
    @symbol=symbol
    @type=type
    @faceValue=faceValue
    @listed_on=listed_on
    p "Insde Constructor"
  end
end

asset = Asset.new("Junk", :junk, Time.current, 0, :jnk)

但我会说使用命名参数,这样人们就不必记住参数 4 的含义。

class Asset
  def initialize (symbol:, name:, type:, listed_on:, faceValue:)
    @name=name
    @symbol=symbol
    @type=type
    @faceValue=faceValue
    @listed_on=listed_on
    p "Insde Constructor"
  end
end

asset = Asset.new(
  name: "Junk",
  type: :junk,
  listed_on: Time.current,
  faceValue: 0,
  symbol: "jnk"
)

这可以通过包含ActiveModel::Model更轻松地完成。你会得到很多方便的东西,比如验证

class Asset
  include ActiveModel::Model
  attr_accessor :symbol, :name, :type, :listed_on, :faceValue

  validates :name, :type, :symbol, presence: true
  validates :faceValue, numericality: { greater_than_or_equal_to: 0 }
end

asset = Asset.new(
  name: "Junk",
  type: :junk,
  listed_on: Time.current,
  faceValue: 0,
  symbol: :jnk
)

推荐阅读