在rails控制台中创建实例时,Rails 4强参数失败

可能在这里做一些蠢事,但这是我的基本cookie切割器类:

class League < ActiveRecord::Base private def league_params params.require(:full_name).permit! end end 

在创建联盟的新实例时:

 2.0.0-p0 :001 > l = League.new(full_name: 'foo', short_name: 'bar') WARNING: Can't mass-assign protected attributes for League: full_name, short_name 

我到底错在了什么? 这是一个Rails 4.0.0.beta1 build + Ruby 2.0

**更新**

我现在意识到强大的参数现在在Controller中实施而不是在模型中。 最初的问题仍然存在。 如果在控制器级别允许它们,如果我在Rails控制台中创建实例,如何正确地将属性列入白名单? 在这种情况下我是否还需要使用attr_accessible ,从而完全复制哪些强参数试图“修复”?

两件事情。 league_params定义在控制器中,而不是模型。 并且params.require()应该包含参数中需要出现的模型的名称,而不是属性。 属性存在检查仍应在模型validation中。 在使用permit!之前,请确保您确实希望允许访问联盟模型中的所有属性permit! 。 所以,它应该是这样的:

 class LeaguesController < ApplicationController private def league_params params.require(:league).permit! end end 

更新:

是的,如果您希望在直接访问模型时限制属性,则需要切换回使用模型中的attr_accessible 。 该function已移至此gem: https : //github.com/rails/protected_attributes 。

我认为如果您直接在控制台中使用模型,则不需要保护属性,因为您确切知道输入的内容。 由于控制台可以完全访问您的应用程序,因此管理整个数据库与恶意分配属性一样容易。

存在强参数attr_accessible的基本安全原因是模型中存在某些不应允许更改的属性,除非它是您的代码的明确意图。

他们之间的细微差别是他们完成工作的透视forms。

StrongParameters专注于用例:可以对每个控制器的操作进行微调,以允许或禁止某些参数,同时考虑任何条件。 总灵活性。

attr_accessible采用不同的视角。 它不是专注于用例,而是专注于角色。 因此,例如,取决于用户的角色,可以改变或不改变某些属性。


使用StrongParameters的方法是在param哈希上应用requirepermit关键字。

require状态指出密钥必须存在于params散列中。 如果没有这样的密钥,则require将引发exception。

permit表示允许使用字段。 任何不允许的密钥都将从哈希中删除,因此不会通过批量分配传递给模型。

模型

 class League attr_protected :final_price # Nobody can mass-assign the final price attr_accessible :winner_name, :as => :jury end 

和控制器

 class LeaguesController < ApplicationController 

这两个动作使用StrongParameters

  # A common user can create a league def create league = League.new(league_params) league.final_price = 1000 league.save redirect_to(league) end # But only the admin can publish a league def publish_league league = League.find(params[:id] league.update_attributes(league_params_as_admin) end 

这个使用attr_accessible

  def publish_the_winner league = League.find(params[:id] # We would expect the current_user.role to return :jury. league.assign_attributes(params[:league], :as => current_user.role) end private def league_params params.require(:league).permit(:name) end def league_params_as_admin params.require(:league).permit(:name, :status) end end 

在我的经验中:

使用强参数的灵活性来微调可以在每个控制器中批量分配的属性。

使用无处不在的attr_accesible来确保无论如何都无法对某些属性进行大规模分配。 例如,在Resque Task中,您可以将用户输入作为参数传递。 您将检查是否使用attr_accesible对某些属性进行了质量分配。

更多信息:

http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

https://github.com/rails/strong_parameters

即使您正在运行Rails 4,白名单似乎仍处于活动状态。您是否从Rails 3应用程序升级到Rails 4? 你在config/application.rb有这个吗?

 config.active_record.whitelist_attributes = true 

仔细检查所有型号上的强参数是否有效。 如果是,则可以将此设置更改为false

另外,请仔细检查模型中是否存在attr_accessible

如果您直接调用模型,那么它将回避您在控制器中实现的任何逻辑。

但是,您可以从控制台调用控制器,然后实现的StrongParameters将生效。

请参阅如何在Rails中从控制台调用控制器/视图方法?