Ruby on rails 4 禁止在具有嵌套属性的生成上出现属性错误
编辑1:这与CanCan gem有关 这是一个嵌套的属性问题。在单一表单上,用户可以创建一个帐户、一个用户帐户(作为“所有者”)和一个团队——所有这些都链接到该帐户。 表单可以很好地处理仅限所有者的嵌套属性,但是一旦我添加了团队嵌套属性,就会得到一个ActiveModel::ForbiddenAttributesError。 我研究了嵌套模型的构建方法,我认为我的语法在我的accounts controller中是正确的——请注意has_one和has_many之间的区别。 我真的撞到墙了。。。 谢谢你的帮助 我的模型是:Ruby on rails 4 禁止在具有嵌套属性的生成上出现属性错误,ruby-on-rails-4,cancan,nested-attributes,Ruby On Rails 4,Cancan,Nested Attributes,编辑1:这与CanCan gem有关 这是一个嵌套的属性问题。在单一表单上,用户可以创建一个帐户、一个用户帐户(作为“所有者”)和一个团队——所有这些都链接到该帐户。 表单可以很好地处理仅限所有者的嵌套属性,但是一旦我添加了团队嵌套属性,就会得到一个ActiveModel::ForbiddenAttributesError。 我研究了嵌套模型的构建方法,我认为我的语法在我的accounts controller中是正确的——请注意has_one和has_many之间的区别。 我真的撞到墙了。。。
class Account < ActiveRecord::Base
RESTRICTED_SUBDOMAINS = %w(www)
has_one :owner, class_name: 'User'
has_many :teams
validates :owner, presence: true
validates :name, presence: true
accepts_nested_attributes_for :owner, :teams
class Team < ActiveRecord::Base
acts_as_tenant :account
has_many :users
belongs_to :account
validates_inclusion_of :active, :in => [true, false]
validates :name, presence: true, allow_nil: false
validates_uniqueness_to_tenant :name
class User < ActiveRecord::Base
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
acts_as_tenant :account
belongs_to :team
validates :lastname, presence: true, allow_nil: false
validates :firstname, presence: true, allow_nil: false
validates_uniqueness_to_tenant :email
def self.current_id
Thread.current_user[:user_id]
end
在我的团队控制员中,我有:
private
def team_params
params.require(:team).permit(:name, :active, :account_id)
end
在我的用户控制器中,我有:
private
def user_params
params.require(:user).permit(:firstname, :lastname, :email, :account_id, :avatar, :role, :street_address, :zip, :city, :phone, :dob, :pob, :citizenship, :team_id, :contract_time)
end
我的表格很长,所以这只是一个摘录:
<%= form_for @account, html: {id: 'accounts-new-form'} do |f| %>
<%= f.fields_for :owner do |o| %>
<%= o.label :firstname, "Your firstname" %>
<%= o.text_field :firstname, options = {class: "form-control required", rel: "FirstName"} %>
<% end %>
<%= f.label :subdomain, "Choose a subdomain" %>
<%= f.text_field :subdomain, options = {class: "form-control required", rel: "Subdomain"} %>
<%= f.fields_for :teams do |t| %>
<%= t.label :name, "Choose a team name" %>
<%= t.text_field :name, options = {class: "form-control required", rel: "Team"} %>
<% end %>
<%= f.submit class: 'btn btn-primary' %>
编辑3:这是我的能力。rb:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :create, Account
# only owner can read & manage Account details
can :manage, Account if user.role == "owner"
cannot :read, Account if user.role == "employee"
cannot :read, Account if user.role == "manager"
# owner has full access to User details, manager can create/edit all User details, employee can read/list other User details
# employee can edit own details except contract information
can :manage, User if user.role == "owner"
can :manage, User if user.role == "manager"
cannot :update, User if user.role == "employee"
can :update, User, :id => user.id # a user can only update its own record
can :avatar, User, :id => user.id # a user can only edit own photo
can :address, User, :id => user.id # a user can only update its own address
can :view_contract, User, :id => user.id # a user cannot updedit own contract infos
can :read, User if user.role == "employee"
can :home, User if user.role == "employee"
end
end
在团队的字段中:
<%= f.fields_for :teams do |t| %>
显然,Rails没有为参数生成teams\u属性,而只是team。由于您没有白名单团队,因此会出现此错误。AccountController中的account\u params方法缺少许多您试图传递的参数。至少,
:名称
,团队:[:名称]
,:子域
和提交
Strong params是一个相当大的混乱来源,所以让我来解释一下实际发生的情况,希望它能帮助您解决自己的问题,这不是真正的禁止属性错误,而是关于不理解Strong_params
基于用户输入创建对象时,可以在模型级别或控制器级别限制访问。在Rails 3中,这是在模型级别,可以访问attr_,但有一个错误,即有人正确地猜测他们完全没有权限分配管理员权限。在Rails 4中,整个体系结构被更改为在控制器级别强制授权。这种变化正是strong_params所做的
现在,在每个控制器中,您都需要手动列出允许通过的内容。您可以使用account_params中使用的require
和permit
方法来执行此操作。您可能已经在教程和示例代码中注意到,每个控制器都在执行类似于mymodel\u params
的操作。然后,在您的#create
和#update
方法中,总是有一行类似于MyModel.new(MyModel_参数)
和@MyModel.update_attributes(MyModel_参数)
这是理解强参数的关键
这里发生的是:
mymodel_params
中,您正在写下要列入白名单的参数列表帐户开始,然后是所有者属性的散列,其中包含团队
。将其与您的帐户参数进行比较,您可以看到缺少一系列属性,并且结构已关闭
tl;drTiago说了什么-您的表单结构不正确。您能完整地发布错误消息吗?谢谢。@EgeErsoz已将完整错误消息添加到bodyJust try@account.teams.build这不是选美比赛。如果你否决了这个问题,请说明原因……这正是我的代码中的内容。我错过什么了吗?对不起。当我看到时,那里什么也没有。@user2721211您应该注意到复数的团队
,它在您的代码中与单数的团队
不同。这导致了错误。更改后,您的参数现在是什么样子?团队的字段
修复了问题的一个方面。但主要问题是AccountsController中的load\u和\u authorize\u资源
声明。实际上,“team”不在“owner\u属性”中。没关系。过来看。但是没有“team”属性,它应该是“teams\u attributes”,因此错误。好的,所有答案都有意义,但我仍然看不到错误的原因。主要是为什么Rails没有为参数生成teams\u属性,而只是team?我查看了表单,看看是否存在结构问题,但似乎没有问题:teams字段\u没有嵌套在owner字段\u中。@ABMagil实际上我的帐户参数包含:name
,:subdomain
和teams\u属性:[:name,:account\u id]
。这就是为什么它如此混乱的原因……所以我最终让Rails在字段中使用team的复数形式来生成teams\u属性,用于:teams
(问题已更新)。注意:它在teams\u属性中生成id,但在owner\u属性中没有生成id——这是一个提示吗?
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :create, Account
# only owner can read & manage Account details
can :manage, Account if user.role == "owner"
cannot :read, Account if user.role == "employee"
cannot :read, Account if user.role == "manager"
# owner has full access to User details, manager can create/edit all User details, employee can read/list other User details
# employee can edit own details except contract information
can :manage, User if user.role == "owner"
can :manage, User if user.role == "manager"
cannot :update, User if user.role == "employee"
can :update, User, :id => user.id # a user can only update its own record
can :avatar, User, :id => user.id # a user can only edit own photo
can :address, User, :id => user.id # a user can only update its own address
can :view_contract, User, :id => user.id # a user cannot updedit own contract infos
can :read, User if user.role == "employee"
can :home, User if user.role == "employee"
end
end
<%= f.fields_for :teams do |t| %>