簡體   English   中英

通過控制器的多態has_many:反模式?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM