over 2 years ago

http://guides.rubyonrails.org/association_basics.html
Active Record Associations
1) 2.4 The has_many :through Association

A has_many :through association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:

兩個model透過第三方的model來進行聯結。

class Physician < ActiveRecord::Base
  has_many :appointments
  has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
  belongs_to :physician
  belongs_to :patient
end
class Patient < ActiveRecord::Base
  has_many :appointments
  has_many :physicians, through: :appointments
end

class Survey < ActiveRecord::Base
  has_many :categories
  has_many :questions, through: :categories
end
class Category < ActiveRecord::Base
  belongs_to :survey
  belongs_to :question
end
class Question < ActiveRecord::Base
  has_many :categories
  has_many :survey, through: :categories
end

The has_many :through association is also useful for setting up "shortcuts" through nested has_many associations. For example, if a document has many sections, and a section has many paragraphs, you may sometimes want to get a simple collection of all paragraphs in the document. You could set that up this way:
:through可以當作捷徑來使用。

class Document < ActiveRecord::Base
  has_many :sections
  has_many :paragraphs, through: :sections
end
class Section < ActiveRecord::Base
  belongs_to :document
  has_many :paragraphs
end
class Paragraph < ActiveRecord::Base
  belongs_to :section
end

class Survey < ActiveRecord::Base
  has_many :categories
  has_many :questions, through: :categories
end
class Category < ActiveRecord::Base
  belongs_to :survey
  has_many :questions
end
class Question < ActiveRecord::Base
  belongs_to :categories
end

With through: :sections specified, Rails will now understand:
@document.paragraphs
@survey.questions

2) 2.8 Choosing Between has_many :through and has_and_belongs_to_many

The simplest rule of thumb is that you should set up a has_many :through relationship if you need to work with the relationship model as an independent entity. If you don't need to do anything with the relationship model, it may be simpler to set up a has_and_belongs_to_many relationship (though you'll need to remember to create the joining table in the database).

You should use has_many :through if you need validations, callbacks, or extra attributes on the join model.

如果需要
validations,
callbacks,
or extra attributes的話,
應該要用 has_many :through

ihower:Rails還有一種舊式的has_and_belongs_to_many方法也可以建立多對多關係,不過已經很少使用,在此略過不提。

3) 2.9 Polymorphic Associations

A slightly more advanced twist on associations is the polymorphic association. With polymorphic associations, a model can belong to more than one other model, on a single association. For example, you might have a picture model that belongs to either an employee model or a product model. Here's how this could be declared:

一個model可以屬於一個以上的model

class Picture < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end
class Employee < ActiveRecord::Base
  has_many :pictures, as: :imageable
end
class Product < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

You can think of a polymorphic belongs_to declaration as setting up an interface that any other model can use. From an instance of the Employee model, you can retrieve a collection of pictures: @employee.pictures.

interface:介面:其他Model可以使用的介面
可以直接下:@employee.pictures 跟 @product.pictures.

class questions < ActiveRecord::Base
  belongs_to :category, polymorphic: true
end
class Survey < ActiveRecord::Base
  has_many :questions, as: :category
end
class Category < ActiveRecord::Base
  has_many :questions, as: :category
end

如果以ihower 的範例來看(https://ihower.tw/rails4/activerecord-relationships.html)
我的案子好像不太適合用polymorphic associations,
我的category應該不太需要更新。

有用的範例:http://www.gotealeaf.com/blog/understanding-polymorphic-associations-in-rails
順便參考一下最下面的:Combining has_many :through and polymorphic association
應用:

一份問卷,有不同的類別,每個類別有許多題目,每個題目有許多選項。

*http://rails101s.logdown.com/posts/211428-active-record-association

代表此變數 ( memebers, participated_groups ) 是經由 ( through ) group_users 這個資料表
來取得 ( user , group ) 資料
(我以為has_and_belongs_to_many才會有group_users這樣的命名方式,原來has_many :through也可以。)

app/models/user.rb
  has_many :group_users
  has_many :participated_groups, :through => :group_users, :source => :group
end
看用戶回答過哪些問題
has_many :answered_questions, :through => :question_users, :source => :question
← ROR TUTORIAL (3RD ED.) Ch2 A toy app RailsFun.tw 新手教學_day2 HD →