【问题标题】:RoR: ActiveRecord::RecordInvalid: Validation failed: Attendee must existRoR:ActiveRecord::RecordInvalid:验证失败:参加者必须存在
【发布时间】:2020-03-30 18:01:30
【问题描述】:

我正在尝试在 RoR 程序中建立 多对多 关联,但我无法摆脱标题中提到的错误,即我在Rails 控制台是:

User.find(1).attended_events = [Event.find(1)]

我需要解决这个问题,但找不到任何地方,感谢任何帮助。

我的代码:

模型

class User < ApplicationRecord
  has_many :created_events,class_name:"Event"
  has_many :hosts
  has_many :attended_events, through: :hosts
end
class Host < ApplicationRecord
  belongs_to :attended_event, class_name:"Event"
  belongs_to :attendee, class_name:"User"
end
class Event < ApplicationRecord
  belongs_to :creator, foreign_key: :user_id, class_name:'User'
  has_many :hosts
  has_many :attendees, through: :hosts
end

迁移文件

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end
class CreateHosts < ActiveRecord::Migration[6.0]
  def change
    create_table :hosts do |t|
      t.references :attendee, null: false, foreign_key: true
      t.references :attended_event, null: false, foreign_key: true
      t.integer :user_id
      t.integer :event_id
      t.timestamps
    end
  end
end
class CreateEvents < ActiveRecord::Migration[6.0]
  def change
    create_table :events do |t|
      t.string :date
      t.text :description
      t.references :user, null: false, foreign_key: true

      t.timestamps
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails model migration many-to-many associations


    【解决方案1】:

    了解foreign_key optionhas_many

    class Event < ApplicationRecord
      belongs_to :creator, foreign_key: :user_id, class_name:'User'
      has_many :hosts
      has_many :attendees, through: :hosts
    end
    

    这些模型关联是错误的,错误在第二行。

    class Event < ApplicationRecord
      belongs_to :creator, foreign_key: :user_id, class_name:'User'
      has_many :hosts
      has_many :attendees, through: :hosts
    end
    

    使用这些模型关联,您需要为has_many :hosts 语句指定foreign_key

    class Host < ApplicationRecord
      belongs_to :attended_event, class_name:"Event"
      belongs_to :attendee, class_name:"User"
    end
    

    以下是我的建议:

    用户

    class User < ApplicationRecord
      has_many :created_events, foreign_key: 'user_id'
      has_many :hosts, foreign_key: 'attendee_id'
      has_many :attended_events, through: :hosts
    end
    

    主持人

    class Host < ApplicationRecord
      belongs_to :attended_event, class_name: 'Event'
      belongs_to :attendee, class_name: 'User'
    end
    

    活动

    class Event < ApplicationRecord
      belongs_to :creator, class_name: 'User'
      has_many :hosts, foreign_key: 'attended_event_id'
      has_many :attendees, through: :hosts
    end
    

    您的主机迁移

    最好避免在此处传递foreign_key,它会在数据库中查找attendees 表和attended_events 表。

    class CreateHosts < ActiveRecord::Migration[6.0]
      def change
        create_table :hosts do |t|
          # t.references :attendee, null: false, foreign_key: true
          t.references :attendee, null: false
          # t.references :attended_event, null: false, foreign_key: true
          t.references :attended_event, null: false
          t.timestamps
        end
      end
    end
    

    【讨论】:

      【解决方案2】:

      通过关联定义source

      class User < ApplicationRecord
        has_many :created_events, class_name:"Event"
        has_many :hosts
        has_many :attended_events, through: :hosts, source: :event
      end
      
      
      class Host < ApplicationRecord
        belongs_to :event
        belongs_to :user
      end
      
      
      class Event < ApplicationRecord
        belongs_to :creator, foreign_key: :user_id, class_name:'User'
        has_many :hosts
        has_many :attendees, through: :hosts, source: :user
      end
      
      
      class CreateHosts < ActiveRecord::Migration[6.0]
        def change
          create_table :hosts do |t|
            t.references :user, null: false, foreign_key: true
            t.references :event, null: false, foreign_key: true
      
            t.timestamps
          end
        end
      end
      

      那你就可以了 User.find(1).attended_events &lt;&lt; Event.find(1)

      【讨论】:

        猜你喜欢
        • 2020-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-23
        • 1970-01-01
        • 2017-12-02
        相关资源
        最近更新 更多