Управление дочерними отношениями с помощью формы вложенного атрибута

StackOverflow https://stackoverflow.com/questions/1240290

Вопрос

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

В любой момент у пользователя может быть 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

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

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

Это было полезно?

Решение

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

Это может работать примерно так:

class User < AB:B

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

end

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

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

Другие советы

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

Однако, чтобы обрабатывать переходы между «ожидающими» профилями и «утвержденными» профилями, я бы предложил добавить конечный автомат для обработки переходов.Камень 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 профиля (один общедоступный, другой ожидающий).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top