RoR: ActiveRecord :: RecordInvalid: проверка не удалась: участник должен существовать - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь сделать ассоциацию многих ко многим в программе 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

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Определить 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 << Event.find(1)

0 голосов
/ 30 марта 2020

Прочтите о опции foreign_key для has_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

Для этих ассоциаций моделей вам необходимо указать foreign_key для оператора has_many :hosts.

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
...