[英]Polymorphic has_many through Controllers: Antipattern?
我很想說是。
一個人為的示例,使用has_many:through和polymorphs:
class Person < ActiveRecord::Base
has_many :clubs, :through => :memberships
has_many :gyms, :through => :memberships
end
class Membership < ActiveRecord::Base
belongs_to :member, :polymorphic => true
end
class Club < ActiveRecord::Base
has_many :people, :through => :memberships
has_many :memberships, :as => :member
end
etc.
目前,撇開健身房是俱樂部還是任何其他設計缺陷的問題。
要將用戶添加到俱樂部,很想保持RESTful風格,然后將一個person_id和club_id張貼到MembersController,如下所示:
form_for club_members_path(@club, :person_id => person.id) ...
在這種情況下,當我們決定這樣做時:
form_for gym_members_path(@gym, :person_id => person.id) ...
我們需要讓MemberController決定父資源是俱樂部還是健身房,並采取相應的行動。 一種非DRY解決方案:
class MembersController < ApplicationController
before_filter :find_parent
...
private
def find_parent
@parent = Gym.find(params[:gym_id]) if params[:gym_id]
@parent = Club.find(params[:club_id]) if params[:club_id]
end
end
如果您不止一次地這樣做,那就太可怕了。
另外,它的概念是加入俱樂部和加入健身房大致相同。 至少,Gym#add_member和Club#add_member或多或少會並行運行。 但是我們必須假設,體育館和俱樂部可能有不同的理由拒絕會員申請。 MemberController需要處理Flash消息並重定向兩個或多個錯誤狀態。
在野外有解決方案。 James Golick的出色ResourceController具有處理parent_type,parent_object等的方式。Revolution On Rails通過向ApplicationController添加一些方法來干燥多個多態控制器是一個不錯的解決方案。 當然,ActionController具有#polymorhpic_url,適用於Blog#posts和Article#posts等較簡單的情況。
這一切讓我感到納悶,是否真的值得將所有這些壓力施加到MembersController上? 在Rails中,多態性處理得很好,但是我的感覺是使用條件(如果/除非/大小寫)清楚地表明您不知道要處理的類型。 元編程有幫助,但僅當類型具有相似的行為時才有用。 兩者似乎都指出需要進行設計審查。
我很想聽聽您對此的想法。 在這種情況下最好干一下,或者確切地知道您擁有哪種父類型? 我在這里神經過敏嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.