Управление дочерними отношениями с помощью вложенной формы атрибута - PullRequest
1 голос
/ 06 августа 2009

Я пытаюсь сделать следующее:

В любой момент у пользователя может быть 1 активный профиль. Этот активный профиль должен быть авторизован администратором, чтобы убедиться, что он соответствует правилам и нормам сайта. Когда пользователь редактирует свой профиль, его общедоступный профиль не изменяется, пока администратор не подпишет свои изменения. Если они вносят изменения в то время, когда их профиль просматривается, их изменения применяются к ожидающему профилю для просмотра и помещаются в конец очереди.

Мои модели выглядят примерно так:

class Profile < AR:B
    belongs_to :user
end

class User < AR:B
    has_many :profiles do
        def active
            ...
        end
        def latest
        end
    end
    def profile
        self.profiles.active
    end
end

Есть один маленький поворот ... пользователь не должен иметь возможности редактировать профиль напрямую, так как коллекция профилей не раскрывается. Вместо этого они редактируют своего пользователя, и там отображаются поля профиля.

Какой лучший способ справиться с этим? В настоящее время я использую:

accepts_nested_attributes_for :profiles

У пользователя, но это кажется довольно хакерским. В идеале большая часть этой логики должна жить в модели, но другая вещь, с которой я заигрываю, это использование презентатора.

Буду признателен за любые мысли, дайте мне знать, если вам нужна дополнительная информация в качестве комментария, и я соответствующим образом обновлю этот пост.

Ответы [ 2 ]

2 голосов
/ 06 августа 2009

Может быть, вам следует попробовать установить два отношения от пользователя к профилю. Один - тот, который они могут редактировать через ваш пользовательский интерфейс, а другой - тот, который утвержден администратором.

Может работать что-то вроде:

class User < AB:B

has_one :profile #the user-editable one one
has_one :active_profile, :class_name=>"profile" #the one shown

end

Каждое изменение в профиле пользователя через форму будет затем отображаться для администратора (с использованием и наблюдателя или, возможно, только и после фильтра). Когда оно одобряется, изменения затем сбрасываются в файл active_profile и показываются где-то.

Таким образом, вы можете иметь чистый интерфейс формы, и всякий раз, когда они редактируют его снова, они видят последний (но не утвержденный) профиль. Вы также можете упорядочить очередь с помощью столбца updated_at, чтобы получить «их изменения применяются к ожидающему профилю для просмотра и помещаются в конец очереди».

1 голос
/ 07 августа 2009

Я бы пошел на это, имея пользовательскую модель с двумя профилями, как было предложено выше. Один «Одобренный» профиль и один для редактирования, который попадает в очередь администратора.

Однако, для обработки переходов между «ожидающими» профилями и «утвержденными» профилями, я бы предложил добавить в конечный автомат для обработки переходов. Драгоценный камень AASM был хорош для меня в недавнем проекте. (http://github.com/rubyist/aasm/tree/master), и я полагаю, что Edge Rails только что испекла State Machinage. (http://github.com/rails/rails/commit/aad5a30bf25d8a3167afd685fc91c99f4f09cc57)

)

Ваша модель может выглядеть примерно так:

class User < AR:B

has_one :active_profile 
has_one :pending_profile

include ActiveRecord:: StateMachine

state_machine do
   state :approved
   state :pending
   state :rejected

   event :update_profile_pending do
    transitions :to => :pending, :from => [:approved], :on_transition => :send_to_admin_queue
  end

   event :update_profile_approved do
    transitions :to => :approved, :from => [:pending], :on_transition => :update_current_profile
   end

   event :update_to_rejected do
    transitions :to => :rejected, :from => [:pending]
  end
end

def send_to_admin_queue
  //method to handlesending pending profiles to admin for approval
end

def update_current_profile
 //method to handle updated profiles with changes
end

end

Затем вы можете вызвать профиль User.update в ожидании! или профиль User.update утвержден! для перехода между состояниями вашего профиля и использования обратных вызовов перехода для обработки отправки данных редактирования между вашим активным профилем и ожидающим профилем.

Что касается использования nested_attributes_for с вашей реальной формой, я не думаю, что это хак, я также использовал его для обновления вложенных атрибутов, и он будет работать нормально. В этом случае вам может и не понадобиться, поскольку у вас есть 2 профиля (один общедоступный, один ожидающий рассмотрения).

Просто идея! Мысли здесь вслух!

...