Rails 与具有嵌套属性的表单关联的问题
Rails issue with the association for a form with nested attributes
我的应用程序中有以下模型:
用户:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
before_destroy { roles.clear }
has_many :users_roles
has_many :roles, through: :users_roles
accepts_nested_attributes_for :roles
#accepts_nested_attributes_for :user_extras
#id :confirmable is activated
def confirmation_required?
false
end
end
角色:
class Role < ApplicationRecord
#before_destroy { users.clear }
has_many :users, through: :users_roles
end
和用户角色:
class UsersRoles < ApplicationRecord
belongs_to :user
belongs_to :role
end
我还有一个接受嵌套属性的表单,看起来像这样:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<%= f.fields_for :roles do |field| %>
<%= field.label :name %></div>
<%= field.text_field :name %>
<% end %>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
我还有一个呈现这种形式的控制器:
class Admin::AccountController < ApplicationController
before_action :authenticate_user!
layout "admin/layouts/dashboard"
def index
@resource = User.new
@resource2 = Role.new
@resource.roles << @resource2
p "==================="
p @resource
p @resource2
p "==================="
@resource.roles.build
# respond_to do |format|
# format.html
# format.json { render json: @resource }
# end
end
private
def admin_account_params
params.require(:resource).permit(:email, :password, :password_confirmation, roles_attributes: [ :name ])
end
end
问题是当我访问该页面时,出现以下错误:
uninitialized constant User::UsersRole
Extracted source (around line #9):
7
8
9
10
11
12
@resource = User.new
@resource2 = Role.new
@resource.roles << @resource2
p "==================="
目前我不确定这有什么问题。如果您能发现问题,那就太好了。提前谢谢了。
模型 class 按照惯例应该是单数,所以模型 class 名称应该是...
class UsersRole < ApplicationRecord
belongs_to :user
belongs_to :role
end
这将自动映射到名为 users_roles
的数据库 table
如果您坚持使用复数 class 名称,那么您需要明确指定 class 名称
has_many :users_roles, class_name: 'UsersRoles'
并且您在 User
模型和 Role
模型中都需要它
我的应用程序中有以下模型:
用户:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
before_destroy { roles.clear }
has_many :users_roles
has_many :roles, through: :users_roles
accepts_nested_attributes_for :roles
#accepts_nested_attributes_for :user_extras
#id :confirmable is activated
def confirmation_required?
false
end
end
角色:
class Role < ApplicationRecord
#before_destroy { users.clear }
has_many :users, through: :users_roles
end
和用户角色:
class UsersRoles < ApplicationRecord
belongs_to :user
belongs_to :role
end
我还有一个接受嵌套属性的表单,看起来像这样:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<%= f.fields_for :roles do |field| %>
<%= field.label :name %></div>
<%= field.text_field :name %>
<% end %>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
我还有一个呈现这种形式的控制器:
class Admin::AccountController < ApplicationController
before_action :authenticate_user!
layout "admin/layouts/dashboard"
def index
@resource = User.new
@resource2 = Role.new
@resource.roles << @resource2
p "==================="
p @resource
p @resource2
p "==================="
@resource.roles.build
# respond_to do |format|
# format.html
# format.json { render json: @resource }
# end
end
private
def admin_account_params
params.require(:resource).permit(:email, :password, :password_confirmation, roles_attributes: [ :name ])
end
end
问题是当我访问该页面时,出现以下错误:
uninitialized constant User::UsersRole
Extracted source (around line #9):
7
8
9
10
11
12
@resource = User.new
@resource2 = Role.new
@resource.roles << @resource2
p "==================="
目前我不确定这有什么问题。如果您能发现问题,那就太好了。提前谢谢了。
模型 class 按照惯例应该是单数,所以模型 class 名称应该是...
class UsersRole < ApplicationRecord
belongs_to :user
belongs_to :role
end
这将自动映射到名为 users_roles
如果您坚持使用复数 class 名称,那么您需要明确指定 class 名称
has_many :users_roles, class_name: 'UsersRoles'
并且您在 User
模型和 Role
模型中都需要它