导入记录时出现rails中的反向有效性错误



使用sidekiq导入记录时,我收到错误ActiveRecord::InverseOfAssociationNotFoundError (Could not find the inverse association for sponsorships (:sponsor_type in LegiscanModel::Sponsorship)。下面是我的模型。

赞助商.rb

class LegiscanModel::Sponsorship < ApplicationRecord
belongs_to :bill, class_name: 'LegiscanModel::Bill', foreign_key: 'bill_id', inverse_of: :sponsorships
belongs_to :sponsor, class_name: 'LegiscanModel::Politician', foreign_key: :politician_id, inverse_of: :sponsorships
accepts_nested_attributes_for :sponsor
delegate :full_name, to: :sponsor, prefix: true, allow_nil: true
validates :politician_id, uniqueness: { scope: :bill }
belongs_to :sponsorship_type, class_name: 'LegiscanModel::SponsorType', foreign_key: :sponsor_type_id, inverse_of: :sponsorships
end

sponsor_type.rb

class LegiscanModel::SponsorType < ApplicationRecord
has_many :sponsorships, class_name: 'LegiscanModel::Sponsorship', inverse_of: :sponsor_type, dependent: :destroy
end

政客.rb

has_many :sponsorships, dependent: :destroy, inverse_of: :sponsor, class_name: 'LegiscanModel::Sponsorship'

sidekiq作业(部分(

def handle_sponsors(sponsors, bill_id)
sponsors.each do |sponsor|
LegiscanModel::Politician.find_by(people_id: sponsor['people_id']).tap do |politician|
LegiscanModel::Sponsorship.find_or_create_by!(politician_id: politician.id, bill_id: bill_id, sponsor_order: sponsor['sponsor_order'], sponsor_type_id: sponsor['sponsor_type_id'])
end
end
end

如果你真的用显式嵌套而不是使用范围解析操作符来正确设置类,你可以极大地改进这个代码:

module LegiscanModel
class Sponsorship < ApplicationRecord
belongs_to :bill
belongs_to :sponsor, 
class_name: 'Politician', # specifying the module is optional
inverse_of: :sponsorships
belongs_to :sponsorship_type
accepts_nested_attributes_for :sponsor
delegate :full_name, to: :sponsor, prefix: true, allow_nil: true
# should be the database column since its used to create a query
validates :politician_id, uniqueness: { scope: :bill_id } 
end
end 
module LegiscanModel
class SponsorshipType < ApplicationRecord
has_many :sponsorships, dependent: :destroy
end
end

虽然这看起来是一个微不足道的风格选择,但事实并非如此——通过使用module LegiscanModel,您可以重新打开模块并设置模块嵌套,以便可以引用同一命名空间中的常量。

这也避免了由于不断增加的常量查找而导致的自动加载错误和错误。::只能在引用常量时使用,而不能在定义常量时使用。

当外键选项可以从关联的名称派生时,也不需要指定外键选项。虽然它没有害处,但它的额外噪音。Rails还可以自动推断反转。如果你想通过联想反射:,你可以检查一下

LegiscanModel::Sponsorship.reflect_on_assocation(:sponsorship_type)
.inverse

最新更新