我正在尝试对字段进行条件验证。这样它只验证另一个字段是否是特定值。这里的问题是,这个其他领域是一对多的关系,我似乎无法让它工作。 以下是相关代码:
class CreateInvolvedPartyTypes < ActiveRecord::Migration
def change
create_table :involved_party_types do |t|
t.string :code
t.string :name
t.timestamps null: false
end
end
end
class CreateInvolvedParties < ActiveRecord::Migration
def change
create_table :involved_parties do |t|
t.string :first_name
t.string :last_name
t.references :involved_party_type
t.timestamps null: false
end
end
end
class InvolvedParty < ActiveRecord::Base
def ipt_cd?
self.involved_party_type.code == 'I'
end
validates :first_name, presence: { message: "Please insert first name" }
validates :last_name, presence: { message: "Please insert last name" }, :if => :ipt_cd?
validates :involved_party_type, presence: { message: "Please select involved party type" }
belongs_to :involved_party_type
end
以上代码失败:
nil的未定义方法`code':NilClass
感谢您的帮助
答案 0 :(得分:1)
错误意味着InvolvedParty中的self.involved_party_type
#ipt_cd?没有。您应该在调用#code之前测试involved_party_type的存在,或者使用#try。
def ipt_cd?
return false if involved_party.nil?
involved_party_type.code == 'I'
end
def ipt_cd?
self.involved_party_type.try(:code) == 'I'
end
或者,如果related_party_type存在,则只能通过调用验证来避免此问题。
validates :last_name, presence: { message: "Please insert last name" }, if: -> { involved_party_type && ipt_cd? }
答案 1 :(得分:0)
我认为问题在于您对调用instance
和class
级别数据感到困惑。
- &#34;实例&#34;每次调用类时都会填充数据
- &#34;级&#34;数据是静态的,总是附加到类
两者之间的结构差异是class
数据通常通过 self (EG def self.method
&amp; self.attribute
)调用,而instance
使用&#34; naked&#34;调用数据属性(IE没有self
)。
您正在调用以下内容:
def ipt_cd?
self.involved_party_type.code == 'I'
end
问题是您引用self
就好像它是类数据一样。你想要的是实例等价物:
def ipt_cd?
involved_party_type.code == 'I'
end
正如另一个答案所述,您的错误是由一段没有code
方法的数据引起的,这意味着它没有。
这是casue(解决方案在上面 - IE删除self
):
involved_party_type.code == 'I'
因此,如果您想确保没有收到此错误,则必须确保involved_party_type
存在。这可以通过首先确保您引用数据的实例变体,然后确保它在那里完成。另一个答案提供了实现这一目标的最佳方法。
最后,我认为你的结构可以改进。
在我看来,引用相关字段的实际数据表示是不好的做法。您是否正在尝试创建新数据,但您是否引用了相关属性?
为什么不这样做:
#app/models/party_type.rb
class PartyType < ActiveRecord::Base
has_many :involved_parties
end
class InvolvedParty < ActiveRecord::Base
belongs_to :party_type
validates :first_name, :party_type, presence: true
validates :last_name, presence: { message: "Please insert last name" }, if: :cd?
private
def cd?
party_type == PartyType.find_by(code: "I").pluck(:id)
end
end
这将发送另一个数据库查询但它会删除对特定数据的依赖性。您当前的设置不依赖于外键,而是依赖于可能更改的值。
虽然此建议还依赖于数据(IE code
== I
),但它会将其用作ActiveRecord
中的量词。也就是说,您不是在比较数据,而是在比较关系。