了解Rails模型关联

时间:2014-11-21 22:08:02

标签: ruby-on-rails rails-activerecord belongs-to has-one

我对Ruby on Rails相对较新,我正在尝试理解主动记录关联的工作方式。到目前为止,我以为我想出来了,但不再确定了。

无论如何,我正在构建我自己的CMS,除了所有,我将专注于我的主要问题。我有一张桌子页面图片

class CreatePages < ActiveRecord::Migration
  def change
    create_table :pages do |t|
      t.string :name
      t.integer :headline_image_id
      t.timestamps
    end

    create_table :pictures do |t|
      t.string   :name
      t.string   :description
      t.string   :image
      t.timestamps
    end
  end
end

有了这个我有我的模特:

class Page < ActiveRecord::Base
  validates :name, presence: true
  validates :headline_image_id, presence: true

  belongs_to :headline_image, class_name: Picture, foreign_key: :headline_image_id
end

class Picture < ActiveRecord::Base
  mount_uploader :image, ImageUploader
end

就是这样。现在我在headline_image_id属性中创建了一张图片和一张图片ID的页面之后,我可以用 @ target_page.headline_image 获取该headline_image。完美,但困扰我的是代码的可读性。如果我将Page模型中的两个模型关联起来会不会更有意义:

class Page < ActiveRecord::Base
  validates :name, presence: true
  validates :headline_image_id, presence: true

  has_one :headline_image, class_name: Picture, foreign_key: :headline_image_id
end

如果我这样做并运行 @ target_page.headline_image ,我会得到一个SQL约束异常,告诉我图片表中没有headline_image_id。

我阅读了所有关于Ruby on Rails指南的Active Record Association教程并观看了所有的codechool Rails课程,我非常确定所有内容都适用于has_one关联......但事实并非如此。

有人可以解释一下吗? 谢谢!

1 个答案:

答案 0 :(得分:4)

Rails Guides解释了您遇到问题的原因。基本上,当您声明belongs_to关系时,外键会出现在声明它的类的表中。声明has_one关系时,外键位于声明中类的表中。

实施例

在这种情况下,pictures表将需要page_id外键。

class Page < ActiveRecord::Base
  has_one :picture
end

class Picture < ActiveRecord::Base
  belongs_to :page 
end

在这种情况下,pages表将需要picture_id外键。

class Page < ActiveRecord::Base
  belongs_to :picture
end

class Picture < ActiveRecord::Base
  has_one :page
end

如果您想使用has_one关联,只需从headline_image_id表中删除pages列,然后在page_id表中添加pictures列。您可以在一次迁移中执行此操作。运行迁移后,按照上面的示例更改模型定义。希望这会有所帮助。