Gerir as relações da criança com um formulário de atributo aninhado
-
11-09-2019 - |
Pergunta
O que eu estou tentando fazer é o seguinte:
No momento ninguém um usuário pode ter um perfil ativo. Este perfil ativo deve ser autorizado por um administrador para se certificar de que ele é compatível com as regras e regulamentos do site. Quando um usuário edita o seu perfil seu perfil público não é afetada até que os sinais de administrador fora de suas alterações. Se eles fazer uma edição, enquanto o seu perfil está em análise, as suas edições são aplicadas ao perfil excelente para revisão e é empurrado para o fim da fila.
As minhas modelos algo parecido com isto:
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
Há um pequeno toque ... o usuário não deve ser capaz de editar o perfil diretamente, como a coleção de perfis não é exposto. Em vez disso, editar o seu utilizador e os campos de perfil são mostrados aqui.
Qual é a melhor maneira de gerenciar isso? Atualmente estou usando:
accepts_nested_attributes_for :profiles
Em que o usuário, mas que parece bastante hacky. Idealmente a maior parte desta lógica viveria no modelo, mas a outra coisa que eu estou flertando com é o uso de um apresentador.
Qualquer pensamento seria muito apreciada, deixe-me saber se você precisar de mais informações como um comentário e eu vou atualizar este post de forma adequada.
Solução
Talvez você deve tentar ter duas relações de usuário para o perfil. Um deles é o que eles podem editar através de sua interface de usuário, eo outro é aquele que é aprovado pelo administrador.
Ele poderia trabalhar algo como:
class User < AB:B
has_one :profile #the user-editable one one
has_one :active_profile, :class_name=>"profile" #the one shown
end
Cada mudanças no perfil do usuário através do formulário, então, mostrar para a administração (usando e observador ou talvez apenas e "after_save" filtro). Quando se Aproves isso, as alterações são, em seguida, despejado para o active_profile, e mostrado em algum lugar.
Dessa forma, você pode ter uma interface de forma limpa, e sempre que editá-lo novamente, eles vêem o último perfil (mas não aprovado). Você também pode solicitar a fila usando a coluna updated_at para ganhar as "suas edições são aplicadas ao perfil excelente para revisão e é empurrado para o fim da fila" funcionalidade.
Outras dicas
eu iria sobre isso por ter o usuário modelo tem um relacionamento com dois perfis como sugerido acima também. Um "Aprovado" perfil, e um para a edição que vai para a sua fila de administração.
No entanto, a fim de lidar com as transições entre "pendente" perfis e "aprovados" perfis sugiro possível inclusão em uma máquina de estado para lidar com as transições. A gema AASM tem sido bom para mim em um projeto recente. ( http://github.com/rubyist/aasm/tree/master ), e eu acredito Edge Rails acaba cozido Estado Machinage direita no bem. ( http://github.com/rails/rails/commit/aad5a30bf25d8a3167afd685fc91c99f4f09cc57 )
Seu modelo poderia ser algo como isto:
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
Você pode então chamar perfil User.update pendente! ou perfil User.update aprovado! a transição entre seus estados de perfil e utilizar os retornos de chamada de transição para lidar com o envio de dados de edição entre o seu perfil ativo e pendentes perfil.
Quanto usando o nested_attributes_for com sua forma atual, eu não acho que é um hack, eu usei-o bem para atualizar atributos aninhados e que iria funcionar bem. Neste caso, porém você pode não precisar de muito desde que você tem 2 perfis (uma pública e uma pendente).
Apenas uma idéia! Pensando alto aqui!