Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 4 禁止在具有嵌套属性的生成上出现属性错误_Ruby On Rails 4_Cancan_Nested Attributes - Fatal编程技术网

Ruby on rails 4 禁止在具有嵌套属性的生成上出现属性错误

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之间的区别。 我真的撞到墙了。。。

编辑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
    中,您正在写下要列入白名单的参数列表
  • strong_params从浏览器中获取原始参数散列,并将您所说的所有安全内容都列为白名单。它会返回一个参数散列的副本,其中只包含白名单上的参数。它还特别标明“嘿,伙计们,很酷,这些是允许的”
  • 如果您正在传递任何未在params散列中列入白名单的内容,并试图用它更新或创建新记录,它会向您抱怨,抛出一个禁止的属性错误,就像这里一样
  • 所以,所有这些都写下来了,问题是你试图在不告诉Rails一切正常的情况下创建一个记录。您可以在错误消息中看到这一点:它写出了您正在传递的参数列表,从
    帐户开始,然后是
    所有者属性的散列,其中包含
    团队
    。将其与您的帐户参数进行比较,您可以看到缺少一系列属性,并且结构已关闭


    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| %>