【问题标题】:has_many :through ,self referential associationhas_many:通过,自引用关联
【发布时间】:2010-02-14 12:34:04
【问题描述】:

我的自引用关联有问题,模型应该给 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 | 
+----+---------------+----------------+---------------------+---------------------+

有什么想法吗?

【问题讨论】:

  • 您是否查看了您的development.log 文件以了解生成的SQL 是什么样的?

标签: ruby-on-rails associations has-many-through


【解决方案1】:

您不会说您使用的是哪个版本的 MySQL、Ruby 或 Rails。我只是用一个小测试应用程序尝试了这个,它工作正常。我在 OS X 10.6 上使用 PostgreSQL 8.4.1。我刚刚在 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

...和 ​​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)

鉴于此:

...还有这个:

...我看不出您的原始代码有什么问题。也许迁移不是您所期望的,也许您没有发布的代码的其他部分正在干扰(例如过滤器、其他 gem),或者 MySQL 的 ActiveRecord 数据库适配器在这种情况下没有做正确的事情和/或 MySQL 运行不正常。安装 PostgreSQL 并使用它而不是 MySQL 进行进一步测试有点冗长,但我认为这是值得的。

以防万一它证明有用,我在这里上传了测试应用程序数据:

如果您发现出了什么问题并设法纠正它,请在此处发布后续信息。如果将来有人遇到类似问题并在寻找解决方案时阅读此线程,这将很有用。

【讨论】:

  • 顺便说一句 - 将 ChunkChunk 重命名为 Binding 可能会使代码更清晰。
【解决方案2】:

这是一个 .reload 问题吗?在控制台中执行此操作后:

right.left_chunks &lt;&lt; left

right.reload

那就试试

right.left_chunks.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-23
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多