我应该使用has_and_belongs_to_many关系吗?

时间:2014-09-09 09:35:16

标签: ruby-on-rails relation

我正在尝试实施赞助商的照片,所以我有我的照片表和我的赞助商表。

赞助商将有很多照片,照片将有很多赞助商。

我是否应该在两个模型中使用 has_and_belongs_to_many 关系?

在那种情况下,

1.。)我应该手动创建连接中间表还是Rails会自动创建它?

2.。)我应该将photo_id添加到sponsorssponsor_id添加到photos吗?

谢谢你们

3 个答案:

答案 0 :(得分:3)

如果您不希望在联接表中包含任何特定信息,那么您会受益于has_and_belongs_to_many。我会向您提供有关has_many :through的信息,以便您了解这两种方法


HABTM

如果您只想关联两个表,则使用

has_and_belongs_to_many

它“愚蠢”,因为它不依赖primary keys - 只在数据表中包含两个foreign_key列。出于这个原因,您不能在连接模型中包含任何特定信息:

enter image description here

这意味着如果您想使用has_and_belongs_to_many,您将能够执行此操作:

#app/models/sponsor.rb
class Sponsors < ActiveRecord::Base
   has_and_belongs_to_many :photos
end

#app/models/photo.rb
class Photo < ActiveRecord::Base
   has_and_belongs_to_many :sponsors
end

然后,您需要创建一个名为[plural_alphabetical_model]_[plural_alphabetical_model]

的联接表
  

$ rails g migration CreatePhotosSponsors

#db/migrate/create_photos_sponsors.rb
class CreatePhotosSponsors < ActiveRecord::Migration
  def self.up
    create_table :photo_sponsors, :id => false do |t|
        t.references :photo
        t.references :sponsor
    end
    add_index :photos_sponsors, [:photo_id, :sponsor_id]
    add_index :photos_sponsors, :sponsor_id
  end

  def self.down
    drop_table :photos_students
  end
end

has_many :through

HABTM方法的替代方案是has_many :through关联。如果要向连接数据添加特定信息,则需要使用此关联。原因是它在数据表中有primary_key(因此可以引用单个记录):

enter image description here

#app/models/student.rb
class Student < ActiveRecord::Base
   has_many :sponsor_photos
   has_many :photos, through: :sponsor_photos
end

#app/models/sponsor_photo.rb
class SponsorPhoto < ActiveRecord::Base
   belongs_to :sponsor
   belongs_to :photo
end

#app/models/photo.rb
class Photo < ActiveRecord::Base
   has_many :sponsor_photos
   has_many :sponsors, through: :sponsor_photos
end

此协会的优点在于您可以在加入模型中包含特定信息,例如支付的价格或其到期日期

答案 1 :(得分:2)

在这种情况下,The has_many :through Association会很好用

sponsor.rb    
 has_many :sponsor_photos, :dependent => :destroy
 has_many :photos, :through => :sponsor_photos


photo.rb
has_many :sponsor_photos, :dependent => :destroy
has_many :sponsors, :through => :sponsor_photos

sponsor_photo.rb
##holding only sponsor_id and photo_id
  belongs_to :sponsor
  belongs_to :photo


###########so now you can use################

@sponsor=Sponsor.first
##get all photos of a  sponsor
@sponsor.photos
@photo=Photo.first
##get all sponsors from a photo
@photo.sponsors

希望这有助于......

答案 2 :(得分:2)

首先是habtm关系,引自'rails 4 way'

  

7.5.1 has_and_belongs_to_many
  在继续本节之前,我必须清楚自己的良心,说明 has_and_belongs_to_many 在许多Rails开发人员(包括本书的作者)的脑海中几乎已经过时了。使用 has_many:通过代替,你的生活应该更容易。

生成一个加入模型SponsorPhoto,例如photo_idsponsor_id

class Sponsor < ActiveRecord::Base
  has_many :photos, through: :sponsor_photos
end

class Photo < ActiveRecord::Base
  has many :sponsors, through :sponsor_photos
end

class SponsorPhoto < ActiveRecord::Base
  belongs_to :sponsors
  belongs_to :photos
end