1

我很想说是的。

一个人为的例子,使用 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) ...

我们需要让 MembersController 决定父资源是 Club 还是 Gym,并采取相应的行动。一种非 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 将以或多或少平行的方式运行。但我们必须假设健身房和俱乐部可能有不同的理由拒绝会员申请。MembersController 需要处理两个或多个错误状态的 flash 消息和重定向。

野外有解决方案。James Golick 很棒的 ResourceController 有一种处理 parent_type、parent_object 等的方法。Revolution On Rails 有一个很好的解决方案,可以通过向 ApplicationController 添加一些方法来干掉多个多态控制器。当然,ActionController 有 #polymorhpic_url 用于更简单的情况,例如 Blog#posts 和 Article#posts 等。

所有这一切让我想知道,是否真的值得将所有压力都施加在 MembersController 上?多态在 Rails 中处理得很好,但我的感觉是使用条件(if/unless/case)清楚地表明你不知道你正在处理什么类型。元编程会有所帮助,但前提是类型具有相似的行为。两者似乎都表明需要进行设计审查。

我很想听听你对此的看法。在这种情况下最好是干,还是确切地知道你有什么父类型?我在这里神经质吗?

4

0 回答 0