嵌套属性并在一个控制器(父控制器)中创建两个独立模型的实例
Nested attributes and creating an instance of two separate models in one controller (parent controller)
我的应用程序有两个模型,租户(公寓)和用户(设计)。我已经这样做了,所以可以使用嵌套属性通过一种形式设置两个模型的属性。问题是提交表单时只创建了一个 Tenant 实例,而不是 User。
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
belongs_to :tenant
# attr_accessible :tenant
end
tenant.rb
class Tenant < ApplicationRecord
after_create :create_tenant
has_many :users
accepts_nested_attributes_for :users
private
def create_tenant
Apartment::Tenant.create(subdomain)
end
end
tenants_controller(不是整个文件)
def new
@tenant = Tenant.new
@user = User.new
render layout: false
end
def create
@tenant = Tenant.new(tenant_params)
@tenant.update_attribute :subdomain, @tenant.company.downcase
respond_to do |format|
if @tenant.save
format.html { redirect_to "http://#{@tenant.subdomain}.lvh.me:3000/users/sign_in", notice: 'Domain was successfully created.' }
#format.html { redirect_to new_user_registration_path, notice: 'Tenant was successfully created.' }
@user = @tenant.users.create(params[:user])
format.json { render :show, status: :created, location: @tenant }
else
format.html { render :new }
format.json { render json: @tenant.errors, status: :unprocessable_entity }
end
end
end
private
def tenant_params
params.require(:tenant).permit(:company, :subdomain,
user_attributes: [ :email, :first_name, :last_name, :password, :password_confirmation ])
end
tenants/new.html.erb(实际上是 _form.html.erb 但它在 tenants/new 中呈现)
<%= form_with(model: tenant, local: true) do |form| %>
<% if tenant.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(tenant.errors.count, "error") %> prohibited this tenant from being saved:</h2>
<ul>
<% tenant.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form.fields_for :user do |f| %>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= form.label :company %>
<%= form.text_field :company %>
</div>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
CLI 中的错误是 unpermitted parameter :user
但属性具有提交表单的正确值:
来自 CLI - 租户创建:
Processing by TenantsController#create as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"a6YvYm/RcMI8phxTmOPD4Vi43ooqE
v0piV5tGvucMK4f7FZSWPmlAGcme+f6Wq+S26+m9ni6fmGBW6t6wZ/yFw==", "tenant"=>{"user"=
>{"first_name"=>"John", "last_name"=>"Smith", "email"=>"jsmith@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "company"=>"Pepsi"},
"commit"=>"Create Tenant"}
Unpermitted parameter: :user
您允许 user_attributes 但将用户作为参数,
更新
<%= form.fields_for :user do |f| %>
和
<%= form.fields_for :users do |f| %>
也更新
params.require(:tenant).permit(:company, :subdomain,
user_attributes: [ :email, :first_name, :last_name, :password, :password_confirmation ])
和
params.require(:tenant).permit(:company, :subdomain,
user_attributes: [:id, :email, :first_name, :last_name, :password, :password_confirmation ])
以便在更新期间不会创建新记录。
我的应用程序有两个模型,租户(公寓)和用户(设计)。我已经这样做了,所以可以使用嵌套属性通过一种形式设置两个模型的属性。问题是提交表单时只创建了一个 Tenant 实例,而不是 User。
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
belongs_to :tenant
# attr_accessible :tenant
end
tenant.rb
class Tenant < ApplicationRecord
after_create :create_tenant
has_many :users
accepts_nested_attributes_for :users
private
def create_tenant
Apartment::Tenant.create(subdomain)
end
end
tenants_controller(不是整个文件)
def new
@tenant = Tenant.new
@user = User.new
render layout: false
end
def create
@tenant = Tenant.new(tenant_params)
@tenant.update_attribute :subdomain, @tenant.company.downcase
respond_to do |format|
if @tenant.save
format.html { redirect_to "http://#{@tenant.subdomain}.lvh.me:3000/users/sign_in", notice: 'Domain was successfully created.' }
#format.html { redirect_to new_user_registration_path, notice: 'Tenant was successfully created.' }
@user = @tenant.users.create(params[:user])
format.json { render :show, status: :created, location: @tenant }
else
format.html { render :new }
format.json { render json: @tenant.errors, status: :unprocessable_entity }
end
end
end
private
def tenant_params
params.require(:tenant).permit(:company, :subdomain,
user_attributes: [ :email, :first_name, :last_name, :password, :password_confirmation ])
end
tenants/new.html.erb(实际上是 _form.html.erb 但它在 tenants/new 中呈现)
<%= form_with(model: tenant, local: true) do |form| %>
<% if tenant.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(tenant.errors.count, "error") %> prohibited this tenant from being saved:</h2>
<ul>
<% tenant.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form.fields_for :user do |f| %>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= form.label :company %>
<%= form.text_field :company %>
</div>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
CLI 中的错误是 unpermitted parameter :user
但属性具有提交表单的正确值:
来自 CLI - 租户创建:
Processing by TenantsController#create as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"a6YvYm/RcMI8phxTmOPD4Vi43ooqE
v0piV5tGvucMK4f7FZSWPmlAGcme+f6Wq+S26+m9ni6fmGBW6t6wZ/yFw==", "tenant"=>{"user"=
>{"first_name"=>"John", "last_name"=>"Smith", "email"=>"jsmith@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "company"=>"Pepsi"},
"commit"=>"Create Tenant"}
Unpermitted parameter: :user
您允许 user_attributes 但将用户作为参数,
更新
<%= form.fields_for :user do |f| %>
和
<%= form.fields_for :users do |f| %>
也更新
params.require(:tenant).permit(:company, :subdomain,
user_attributes: [ :email, :first_name, :last_name, :password, :password_confirmation ])
和
params.require(:tenant).permit(:company, :subdomain,
user_attributes: [:id, :email, :first_name, :last_name, :password, :password_confirmation ])
以便在更新期间不会创建新记录。