Ruby on rails 使Rails类属性不可访问-Rails教程第9章,练习1
我正在学习Michael Hartl的Rails教程。我来了。它要求您添加一个测试来验证Ruby on rails 使Rails类属性不可访问-Rails教程第9章,练习1,ruby-on-rails,railstutorial.org,Ruby On Rails,Railstutorial.org,我正在学习Michael Hartl的Rails教程。我来了。它要求您添加一个测试来验证User类的admin属性是否不可访问。以下是注释掉不相关部分的用户类: class User < ActiveRecord::Base attr_accessible :name, :email, :password, :password_confirmation attr_protected :admin # before_save methods # validations
User
类的admin
属性是否不可访问。以下是注释掉不相关部分的用户类:
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
attr_protected :admin
# before_save methods
# validations
# private methods
end
测试失败了。它说,尽管
admin
属性受到保护,但没有引发任何错误。如何才能通过考试?这只适用于批量作业,如从表单提交设置字段。试着这样做:
@user.update_attrtibutes(:admin => true)
@user.admin.should be_false
正如Rails文档所声称的,attr_受保护 此宏中命名的属性不受批量分配的影响,例如new(属性)、update_属性(属性)或Attributes=(属性)
所以您可以手动更改字段。”attr_protected“仅与质量分配有关 来自Ruby文档: 批量分配安全性提供了一个接口,用于保护属性不受最终用户分配的影响 请尝试此代码
describe "accesible attributes" do
it "should not allow access to admin" do
expect do
User.new(admin: true)
end.should raise_error(ActiveModel::MassAssignmentSecurity::Error)
end
end
根据提示,我首先在app/models/user.rb中将
:admin
添加到attr\u accessible
,以红色开头。
然后我添加了测试:
describe "admin attribute" do
it "should not be accessible" do
expect do
@user.update_attributes(:admin => true)
end.to raise_error(ActiveModel::MassAssignmentSecurity::Error)
end
end
符合规格,并得到一个红色。
从user.rb中删除:admin
,我得到一个绿色。到目前为止还不错。
让我困惑的是我为什么要使用sintax:
@user.update_attributes(:admin => true)
而不是
@user.admin=true
(我检查了,在本例中它不起作用)。@agaved。这个答案可能来得晚,你可能已经有了答案,但我想回答你的问题,它可能会帮助其他人
了解update\u attributes
与直接分配有何不同的最佳方法@user.admin=true
就是尝试在控制台中执行此操作。如果您正在学习Hartl的教程,请尝试以下操作:
@user = User.first
@user.admin?
=> true
@user.admin = false
=> false
直接分配管理将用户的属性admin的值从true
更改为false
,而不会引起批量分配错误。这是因为在调用update\u attributes
或使用不可访问的属性创建新用户user.new
时会引发批量分配错误。换句话说,当用户试图更新(attribute\u update)
或创建user.new(admin:true)
一个属性不可访问的新用户时,Rails会引发大量分配错误。在上述情况下,直接分配不使用用户控制器的创建或更新方法
它们是非常相似的代码片段,因为在上述情况下,您可以使用@user.save!(validate:false)
直接在IRB中,但正如我上面所说的,这不会使用用户控制器的创建或更新方法,因此不会抛出错误
我希望这对我有帮助。[剧透警报:如果你想自己解决Hartl书中的练习,我很确定我会给出答案。尽管被接受的答案是有趣的信息,但我不相信这是Hartl的想法,因为这需要书中没有涵盖的知识,也没有具体说明通过网络操作或使用他提供的测试更新。] 如果我没弄错的话,我想你可能会认为这个练习比实际困难得多。首先,你误解了这个暗示: 提示:您的第一步应该是将admin添加到user_params中允许的参数列表中 它没有说要在类中更改其attr声明。它说要修改帮助函数user_params。因此我将其添加到users_controller.rb中的列表中:
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation, :admin)
end
接下来,我将清单9.48中的代码复制到spec/requests/user\u pages\u spec.rb中指定的位置:
require 'spec_helper'
describe "User pages" do
.
.
.
describe "edit" do
.
.
.
describe "forbidden attributes" do
let(:params) do
{ user: { admin: true, password: user.password,
password_confirmation: user.password } }
end
before do
sign_in user, no_capybara: true
patch user_path(user), params
end
specify { expect(user.reload).not_to be_admin }
end
end
end
然后测试失败,表明可以传入admin参数,从而将普通用户更改为admin,这不是您希望允许的:
$ rspec spec
.....................[edited out dots].................................F
Failures:
1) User pages edit forbidden attributes
Failure/Error: specify { expect(user.reload).not_to be_admin }
expected admin? to return false, got true
# ./spec/requests/user_pages_spec.rb:180:in `block (4 levels) in <top (required)>'
Finished in 4.15 seconds
91 examples, 1 failure
Failed examples:
rspec ./spec/requests/user_pages_spec.rb:180 # User pages edit forbidden attributes
现在,尝试使用新的admin值修补用户失败……测试成功,验证“admin属性不能通过web编辑”
$ rspec spec
.....................[edited out dots].................................F
Failures:
1) User pages edit forbidden attributes
Failure/Error: specify { expect(user.reload).not_to be_admin }
expected admin? to return false, got true
# ./spec/requests/user_pages_spec.rb:180:in `block (4 levels) in <top (required)>'
Finished in 4.15 seconds
91 examples, 1 failure
Failed examples:
rspec ./spec/requests/user_pages_spec.rb:180 # User pages edit forbidden attributes
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
$ rspec spec
...........................................................................................
Finished in 4.2 seconds
91 examples, 0 failures