Рельсы не создают промежуточную таблицу? - Habtm отношения - PullRequest
4 голосов
/ 21 июня 2011

Таблица между моделью User и моделью Period не существует.У них есть отношения has_many_and_belongs_to.Я все еще изучаю Rails, поэтому, пожалуйста, потерпите меня.

Это содержимое файла модели User.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me

  has_many :assignments, :order => "end"
  has_and_belongs_to_many :periods
end

Это содержимое файла модели Period.rb

class Period < ActiveRecord::Base
  has_many :weights
  has_many :assignments
  has_and_belongs_to_many :users
end

Точное сообщение об ошибке Could not find table 'periods_users'.Это происходит, когда экземпляр Period или User пытается вызвать пользователей или периоды (например, new_user.periods или new_period.users)

Я использую SQLite 3 для базы данных разработки, и SQLite 3 установлен правильно.

Я предполагал, что Rails создаст промежуточные таблицы для отношений habtm.Нужно ли создавать их самому, и если да, то как?

(Обратите внимание, что ассоциации других моделей работают просто отлично)

Если я не предоставляю достаточно информациипожалуйста, дайте мне знать.

edit: после попытки метода B он выдал:

undefined method "klass" for nil:NilClass

Это произошло при попытке управления моделями User и Period в rails_admin

Итак, я удалил новую модель и попробовал метод А. Она выкинула

undefined method "period_id" for <ActiveRecord::ConnectionAdapters::SQlite3Adapter:0x3df7760>

при попытке запустить

rake db:migrate

Вот миграция:

class CreateTablePeriodsUsers < ActiveRecord::Migration
  def self.up
    create_table 'periods_users' do |t|
      t.integer period_id
      t.integer user_id
    end
  end

  def self.down
    drop_table 'periods_users'
  end
end

edit # 2

Теперь он имеет "create_has_and_belongs_to_many_reflection: Primary Key is not allowed in a has_and_belongs_to_many join table"

Это произошло после попытки запустить "сервер rails", идо этого я запускал rake db:migrate успешно

edit # 3:

Я исправил это чуть меньше недели назад, в итоге это стало проблемой со схемой базы данных, поэтому я просто отбросилбазу данных и перенастроили, и она работала нормально.

Ответы [ 2 ]

5 голосов
/ 21 июня 2011

Вы должны создать их самостоятельно, да, есть два способа сделать это.

a) Просто создать миграцию с новой таблицей.

b) Создать новую модель для использованиядля ассоциации HABTM (это упрощает удаление ассоциации).

Метод A:

$ rails generate migration CreateTablePeriodsUsers

Затем отредактируйте вновь созданный файл миграции,

class CreateTablePeriodsUsers < ActiveRecord::Migration                                                                                                                                                                                                                                                                                                           
  def up
    create_table 'periods_users' do |t|
      t.integer :period_id
      t.integer :user_id
    end
  end

  def down
    drop_table 'periods_users'
  end
end

Запустите rake db:migrate, и вы должны установить.

Метод B:

$ rails generate model PeriodsToUser period_id:integer user_id:integer

Редактировать модель PeriodsToUsers

class PeriodToUser < ActiveRecord::Base
  belongs_to :period
  belongs_to :user
end

Затем измените ваши модели, чтобы использовать опцию :through.

class Period < ActiveRecord::Base
  # ...
  has_many :users, :through => :period_to_user
end

class User < ActiveRecord::Base
  # ...
  has_many :periods, :through => :period_to_user
end

Райан Бейтс имеет хороший пример этого метода на своем сайте, https://github.com/ryanb/railscasts/blob/master/app/models/tagging.rb

0 голосов
/ 25 июня 2013

Чтобы создать отношение has_many_belongs_to_many с помощью предложения has_many с параметром до , выполните следующие действия:

  1. Создайте таблицу один (например, пользователи)
  2. Создать таблицу два (например: роли)
  3. Создать следующую миграцию:

rails генерировать модель RolesToUsers пользователь: assign_to роль: own_to

, где RolesToUsers может быть любым именем, а пользователь и роль не во множественном числе (реальные имена таблиц пользователи и ролей - во множественном числе).

Итак, нужно создать что-то похожее на следующую миграцию:

class RolesToUsers < ActiveRecord::Migration
  def change
    create_table :roles_to_users do |t|
      t.belongs_to :user
      t.belongs_to :role

      t.timestamps
    end
    add_index :roles_to_users, :user_id
    add_index :roles_to_users, :role_id
  end
end

с соответствующей моделью:

class RolesToUsers < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
  # attr_accessible :title, :body
end

Наконец, вам нужно только добавить предложение has_many с через в двух моделях следующим образом:

В users.rb file:

has_many :roles_to_users
has_many :roles, through: :roles_to_users

В файле role.rb :

has_many :roles_to_users
has_many :users, through: :roles_to_users
...