繁体   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