Почему я не могу использовать ассоциацию t 1: m в обеих таблицах для формирования ассоциации am: m? - PullRequest
0 голосов
/ 10 декабря 2010

Я новичок в рельсах, я думал об этой идее сегодня днем ​​

вот мой код:

файл миграции видео таблицы:

class CreateVideos < ActiveRecord::Migration
  def self.up
    create_table :videos do |t|
      t.string :title
      t.string :drummer_id

      t.timestamps
    end
  end

  def self.down
    drop_table :videos
  end
end

таблица барабанщикафайл миграции:

class CreateDrummers < ActiveRecord::Migration
  def self.up
    create_table :drummers do |t|
      t.string :first_name
      t.string :video_id
      t.timestamps
    end
  end

def self.down drop_table: конец барабанщика

drummer.rb

class Drummer < ActiveRecord::Base
 belongs_to :video
 has_many :videos 
end

video.rb

класс Video

насколько я знаю

Drummer.create(:first_name => "Jojo")

Drummer.find_by_first_name("Jojo").videos.create(:title => "JojoVideo1")

все нормально

но с другой стороны ничего нет!

Video.find_by_title("JojoVideo1").drummers
=>[]

Я проверяю все внешние ключи на совпадение, но я не знаю, что запрос выше возвращает пустой массив.

Ответы [ 2 ]

1 голос
/ 10 декабря 2010
 > Drummer.all
 => [#<Drummer id: 1, first_name: "Jojo", video_id: nil, created_at: "2010-12-10 11:04:48", updated_at: "2010-12-10 11:04:48">] 
 > Video.all
 => [#<Video id: 1, title: "JojoVideo1", drummer_id: "1", created_at: "2010-12-10 11:04:48", updated_at: "2010-12-10 11:04:48">] 
 > Video.all.first.drummer
 => #<Drummer id: 1, first_name: "Jojo", video_id: nil, created_at: "2010-12-10 11:04:48", updated_at: "2010-12-10 11:04:48"> 
 > Video.all.first.drummers
 => [] 

И из test / development.log:

  Video Load (0.3ms)  SELECT "videos".* FROM "videos"
  Drummer Load (0.3ms)  SELECT "drummers".* FROM "drummers" WHERE ("drummers"."id" = 1) LIMIT 1
  Video Load (0.3ms)  SELECT "videos".* FROM "videos"
  Drummer Load (0.3ms)  SELECT "drummers".* FROM "drummers" WHERE ("drummers".video_id = 1)

Video.all.first.drummer работает, потому что он найден при переходе к видео и проверке их идентификатора барабанщика.Другой не работает, потому что он пытается найти барабанщиков с video_id, и способ, которым мы создали видео, не устанавливал video_id барабанщика.

Мы можем создать пару видео / барабанщик с противоположной проблемой:

d = Drummer.first
d.create_video(:title => "JojoVideo2")
d.save

Это новое видео хорошо работает для барабанщиков, но плохо для барабанщика - потому что на этот раз у барабанщика есть video_id, но у видео нет drummer_id.

Практический результат которогочто ты должен делать то, что сказал Рохит:)

1 голос
/ 10 декабря 2010

Я не знаю, что не так в вашем коде. Но я хотел бы предложить другой путь. Вы можете создать модель соединения, которая будет обрабатывать ассоциацию «многие ко многим». Используя модель соединения, вы можете лучше контролировать свой код. Это можно сделать, как показано ниже:

class A < ActiveRecord::Base
has_many :cs
has_many :bs, :through => cs
end

class B < ActiveRecord::Base
has_many :cs
has_many :as, :through => cs
end

class C < ActiveRecord::Base
belongs_to :as
belongs_to :bs
end

и миграция для каждой модели, как показано ниже

class CreateAs < ActiveRecord::Migration
  def self.up
    create_table :as do |t|
      t.string :title
      t.timestamps
    end
  end

  def self.down
    drop_table :as
  end
end


class CreateBs < ActiveRecord::Migration
  def self.up
    create_table :bs do |t|
      t.string :title
      t.timestamps
    end
  end

  def self.down
    drop_table :bs
  end
end


class CreateCs < ActiveRecord::Migration
  def self.up
    create_table :cs do |t|
      t.references :as
      t.references :bs
      t.timestamps
    end
  end

  def self.down
    drop_table :cs
  end
end

Другой способ - просто создать таблицу соединений без модели. Это может быть сделано: -

класс A

класс B

Надеюсь, у вас есть идея получше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...