У меня есть две модели: одна для контактов ("Contatos") и одна для пользователей ("Usuarios").Contatos has_one
Usuario, как указано ниже:
class Contato < ApplicationRecord
has_one :usuario, dependent: :destroy
accepts_nested_attributes_for :usuario,
allow_destroy: true
И
class Usuario < ApplicationRecord
has_secure_password
belongs_to :contato
validates_presence_of :login, :password
validates_uniqueness_of :login
end
Я хочу использовать одну форму для создания и редактирования обеих моделей.Часть _form, которая у меня сейчас есть, такова:
<%= form_with(model: contato, local: true) do |contato_form| %>
<%= if contato.errors.any?
showferr contato
end %>
#Here are the inputs for contato, I cut them out so it wouldn't be too long to read.
Ниже (тот же файл, что и выше) есть флажок для модели Contato
, которую я оставил, она устанавливает Boolean
вмодель (и БД), сообщающая, что у пользователя нет контакта, кроме того, я использую некоторую JavaScript (Coffee)
до toggle
часть формы пользователя (Usuario)
, основанную на значении флажка.
<div class="form-group">
<%= contato_form.label :possui_usuario, :class => 'inline-checkbox' do %>
Possui usuário
<%= contato_form.check_box :possui_usuario, {id: "hasUser", checked: @contato.possui_usuario} %>
<% end %>
</div>
</div>
<div id="userPart" class="findMe" <% unless @contato.possui_usuario %> style="display:none;" <% end %> >
<h2> Usuário: </h2>
<div class="container">
<%= contato_form.fields_for :usuario, @contato.usuario do |usuario_form| %>
<%= render partial: 'usuarios/campos_usuario', locals: {form: usuario_form, object: @contato} %>
<% end %>
</div>
</div>
<br/>
<div class="container-fluid text-right">
<%= contato_form.submit 'Confirmar', :class => 'btn-lg btn-success' %>
</div>
<% end %>
частичная форма для модели Usuario отображается нормально, но я хочу создать и / или проверить пользовательскую часть, только если установлен флажок (если я скажу, что у контакта есть пользователь).
Вот что я пытался в последний раз (было много попыток):
На Contato
модель:
attr_accessor(:has_user)
@has_user = 0
before_validation do |record|
@has_user = record.possui_usuario
end
def self.user?
@has_user == 1
end
validates_presence_of :nome
validates_length_of :nome, in: 1..45
validates_presence_of :email
validates_format_of :email, with: email_regex
validates_associated :usuario, if: user?
Контроллер для Contato
:
class ContatosController < ApplicationController
before_action :set_contato, only: [:show, :edit, :update, :destroy]
# GET /contatos
# GET /contatos.json
def index
@contatos = Contato.all
@page_title = 'Contatos'
end
# GET /contatos/1
# GET /contatos/1.json
def show
@page_title = 'Ver contato: ' + @contato.nome
end
# GET /contatos/new
def new
@contato = Contato.new
@contato.build_usuario
@contato.ativo = true
@page_title = 'Novo contato'
end
# GET /contatos/1/edit
def edit
@page_title = 'Editar contato: ' + @contato.nome
unless @contato.possui_usuario
@contato.build_usuario
end
end
# POST /contatos
# POST /contatos.json
def create
@contato = Contato.new(contato_params)
respond_to do |format|
if @contato.save
flash[:notice] = 'Contato foi criado com sucesso.'
format.html {redirect_to @contato}
format.json {render :show, status: :created, location: @contato}
else
flash[:warn] = "Erro ao criar contato."
format.html {render :new}
format.json {render json: @contato.errors, status: :unprocessable_entity}
end
end
end
# PATCH/PUT /contatos/1
# PATCH/PUT /contatos/1.json
def update
respond_to do |format|
if @contato.update(contato_params)
format.html {redirect_to @contato, notice: 'Contato foi atualizado com sucesso.'}
format.json {render :show, status: :ok, location: @contato}
else
format.html {render :edit}
format.json {render json: @contato.errors, status: :unprocessable_entity}
end
end
end
# DELETE /contatos/1
# DELETE /contatos/1.json
def destroy
@contato.destroy
respond_to do |format|
format.html {redirect_to contatos_url, notice: 'Contato deletado com sucesso.'}
format.json {head :no_content}
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_contato
@contato = Contato.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def contato_params
params.require(:contato).permit(:id, :empresa_id,
:ativo, :nome,
:cargo, :celular,
:email, :nascimento,
:observacoes, :mensagem_instantanea,
:tipo_msg_inst, :possui_usuario,
usuario_attributes: [:login, :password, :permissoes, :id, :contato_id, :_destroy])
end
end
Извините за длинный вопрос и большие блоки кода.