has_many: сквозная, самоссылочная ассоциация - PullRequest
1 голос
/ 14 февраля 2010

У меня проблемы с самоссылочной ассоциацией, модели должны предоставить ma массив моделей для методов left_chunks и right_chunks, но я получаю каждый раз пустой массив

Источник

class Chunk < ActiveRecord::Base
  has_many :left_bindings, :foreign_key => "left_chunk_id",
   :class_name => "ChunkChunk",
   :dependent => :destroy
  has_many :right_chunks, :through => :left_bindings
  has_many :right_bindings, :foreign_key => "right_chunk_id",
   :class_name => "ChunkChunk",
   :dependent => :destroy
  has_many :left_chunks, :through => :right_bindings
end

class ChunkChunk < ActiveRecord::Base
 belongs_to :left_chunk, :class_name => "Chunk", :foreign_key => "left_chunk_id"
 belongs_to :right_chunk, :class_name => "Chunk", :foreign_key => "right_chunk_id"
end

Вывод из ./script/console

>> #first case
?> 
?> left = Chunk.new({:content => "chunk_one"}); left.save
=> true
>> right = Chunk.new({:content => "chunk_two"}); right.save
=> true
>> left.right_chunks << right
=> []
>> left.right_chunks
=> []
>> left.left_chunks
=> []
>> 
?> #second case
?> 
?> left = Chunk.new({:content => "chunk_three"}); left.save
=> true
>> right = Chunk.new({:content => "chunk_four"}); right.save
=> true
>> right.left_chunks << left
=> []
>> right.left_chunks
=> []
>> right.right_chunks
=> []

Почему куски не связаны друг с другом?

База данных после выполнения кода

mysql> select * from chunks;
+----+-------------+---------------------+---------------------+
| id | content     | created_at          | updated_at          |
+----+-------------+---------------------+---------------------+
|  1 | chunk_one   | 2010-02-14 12:11:22 | 2010-02-14 12:11:22 | 
|  2 | chunk_two   | 2010-02-14 12:11:22 | 2010-02-14 12:11:22 | 
|  3 | chunk_three | 2010-02-14 12:11:22 | 2010-02-14 12:11:22 | 
|  4 | chunk_four  | 2010-02-14 12:11:22 | 2010-02-14 12:11:22 | 
+----+-------------+---------------------+---------------------+

mysql> select * from chunk_chunks;
+----+---------------+----------------+---------------------+---------------------+
| id | left_chunk_id | right_chunk_id | created_at          | updated_at          |
+----+---------------+----------------+---------------------+---------------------+
|  1 |          NULL |              2 | 2010-02-14 12:11:22 | 2010-02-14 12:11:22 | 
|  2 |             3 |           NULL | 2010-02-14 12:11:22 | 2010-02-14 12:11:22 | 
+----+---------------+----------------+---------------------+---------------------+

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 14 февраля 2010

Вы не говорите, какую версию MySQL, Ruby или Rails вы используете.Я только что попробовал это с небольшим тестовым приложением, и оно работало правильно.Я использую PostgreSQL 8.4.1 на OS X 10.6.Я только что создал пустое приложение на Rails 2.3.5 / Ruby 1.8.7 (2009-06-12 patchlevel 174) с помощью "rails testapp", затем добавил две модели в chunk.rb:

class Chunk < ActiveRecord::Base
  has_many :left_bindings,  :foreign_key => "left_chunk_id",
                            :class_name => "ChunkChunk",
                            :dependent => :destroy
  has_many :right_chunks,   :through => :left_bindings
  has_many :right_bindings, :foreign_key => "right_chunk_id",
                            :class_name => "ChunkChunk",
                            :dependent => :destroy
  has_many :left_chunks,    :through => :right_bindings
end

...and chunk_chunks.rb:

class ChunkChunk < ActiveRecord::Base
 belongs_to :left_chunk,  :class_name => "Chunk", :foreign_key => "left_chunk_id"
 belongs_to :right_chunk, :class_name => "Chunk", :foreign_key => "right_chunk_id"
end

... плюс две миграции для добавления таблиц без кратких временных отметок:

class AddChunks < ActiveRecord::Migration
  def self.up
    create_table 'chunks' do | t |
      t.string :content
    end
  end

  def self.down
    drop_table 'chunk'
  end
end

... и:

class AddChunkChunks < ActiveRecord::Migration
  def self.up
    create_table 'chunk_chunks' do | t |
      t.belongs_to :left_chunk
      t.belongs_to :right_chunk
    end
  end

  def self.down
  end
end

Затем я запустил «rake db: create», «rake db: migrate», и ваши консольные команды работали для меня следующим образом:

PondPro:testapp adh1003$ script/console
Loading development environment (Rails 2.3.5)
>> left = Chunk.new({:content => "chunk_one"}); left.save
=> true
>> right = Chunk.new({:content => "chunk_two"}); right.save
=> true
>> left.right_chunks << right
=> [#<Chunk id: 2, content: "chunk_two">]
>> left.right_chunks
=> [#<Chunk id: 2, content: "chunk_two">]
>> left.left_chunks
=> []
>> left = Chunk.new({:content => "chunk_three"}); left.save
=> true
>> right = Chunk.new({:content => "chunk_four"}); right.save
=> true
>> right.left_chunks << left
=> [#<Chunk id: 3, content: "chunk_three">]
>> right.left_chunks
=> [#<Chunk id: 3, content: "chunk_three">]
>> right.right_chunks
=> []

Содержимое базы данных после вышесказанного было:

chunk-devel=# SELECT * FROM chunks;
 id |   content   
----+-------------
  1 | chunk_one
  2 | chunk_two
  3 | chunk_three
  4 | chunk_four
(4 rows)

chunk-devel=# SELECT * FROM chunk_chunks;
 id | left_chunk_id | right_chunk_id 
----+---------------+----------------
  1 |             1 |              2
  2 |             3 |              4
(2 rows)

Учитывая это:

... и это:

... Я не вижу ничего действительно плохого в вашем исходном коде.Возможно, миграции не соответствуют вашим ожиданиям, возможно, есть другие части вашего кода, которые вы не опубликовали, которые мешают (например, фильтры, другие гемы) или, возможно, адаптер базы данных ActiveRecord для MySQL не делает правильные вещи в этом случаеи / или MySQL не работает должным образом.Немного скучно установить PostgreSQL и использовать его вместо MySQL для дальнейших тестов, но я думаю, что это будет полезно.

На всякий случай, если это окажется полезным, я загрузил данные тестового приложения.здесь:

Если вы обнаружите, что пошло не так и вам удастся это исправить, пожалуйста, опубликуйте продолжение здесь.Это будет полезно, если в будущем кто-нибудь столкнется с подобной проблемой и прочитает эту ветку во время поиска решения.

0 голосов
/ 15 февраля 2010

Это проблема .reload?После того, как вы выполните это в консоли:

right.left_chunks << left

do

right.reload

, затем попробуйте

right.left_chunks.

...