Полиморфный has_many через контроллеры: Antipattern? - PullRequest
1 голос
/ 18 февраля 2010

Я испытываю желание сказать да.

Придуманный пример, использующий has_many: through и полиморфы:

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 и POST 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 решить, является ли родительский ресурс Клубом или Тренажерным залом, и действовать соответствующим образом.Одно неСУХОЕ решение:

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 должен обрабатывать флэш-сообщения и перенаправления для двух или более состояний ошибки.

Существуют решения в дикой природе.У потрясающего ResourceController от Джеймса Голика есть способ работы с parent_type, parent_object и т. Д. Revolution On Rails имеет хорошее решение для СУШКИ нескольких полиморфных контроллеров путем добавления некоторых методов в ApplicationController.И, конечно, у ActionController есть #polymorhpic_url для более простых случаев, таких как сообщения в блоге # и статьи # и т. Д.

Все это заставляет меня задуматься, стоит ли вообще оказывать такое давление на MembersController?Полиморфизм довольно хорошо обрабатывается в Rails, но я чувствую, что использование условных выражений (если / если / без) является четким признаком того, что вы не знаете, с каким типом вы имеете дело.Метапрограммирование помогает, но только когда типы имеют похожее поведение.Оба, похоже, указывают на необходимость пересмотра дизайна.

Я хотел бы услышать ваши мысли по этому поводу.Лучше быть СУХИМ в этом сценарии или точно знать, какой у вас родительский тип?Я здесь невротик?

1 Ответ

0 голосов
/ 24 января 2012

Я думаю, что эта ссылка дает ответ на ваш вопрос http://revolutiononrails.blogspot.com/2007/05/drying-up-polymorphic-controllers.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...