English 中文(简体)
第九章,第1项行动
原标题:Make Rails Class Attribute Inaccessible - Rails Tutorial Chapter 9, Exercise 1

我通过Michael Hartl 的铁路教程工作。 我来到< a href=> http:// ruby.railstutominal.org/ chaples/update-showing-and-deleting-users#sec% 3aupdateting_deleting_exercises> rel=“nofollow” > captail 9Capt 1 production 1 。 它要求您添加一个测试, 以核实 < code> User 类的 < code > 属性无法访问 。 这里的用户类中含有不相关的部分评论 :

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation
  attr_protected :admin

  # before_save methods
  # validations
  # private methods
end

在此测试 Im 用于验证 < code>admin 属性无法访问 。

describe User do
  before do
    @user = User.new( 
                     name: "Example User",
                     email: "[email protected]",
                     password: "foobar123",
                     password_confirmation: "foobar123")
  end

  subject { @user }

  describe "accessible attributes" do
    it "should not allow access to admin" do
      expect do
        @user.admin = true 
      end.should raise_error(ActiveModel::MassAssignmentSecurity::Error)
    end
  end
end

测试失败。 它说没有出现错误, 尽管 < code> admin 属性受到保护 。 我如何才能通过测试?

最佳回答

Ruby 文档中的 Ruby 文档 :

大规模派任安全为保护特性免受最终用户派任的影响提供了一个接口。

问题回答

As Rails Docs 索赔关于Attr保护费的索赔

此宏中命名的属性不受质量分配的保护, 如新( 属性) 、 更新_ 属性( 属性) 、 或属性= ( 属性) 。

所以您可以手动更改字段。 attr_ protected 只涉及大规模任务。

仅用于质量任务, 如从表单提交的表格中设置字段。 尝试类似的东西 :

@user.update_attrtibutes(:admin => true)
@user.admin.should be_false

[Spoiler警告:如果你试图单独解决哈特尔书中的练习,我敢肯定我即将给出答案。尽管已经接受的答案是有趣的信息,但我不认为这是哈特尔的想法,因为这需要知道这本书没有覆盖的内容,也没有具体涉及通过网络行动更新或使用他提供的测试。 ]

我认为你可能认为这次演习比实际要难得多 如果我说对了的话。 首先,你误解了暗示:

提示: 您的第一步应该是将管理员添加到 user_ param 中允许参数列表中 。

它没有说要更改在类中的 attr 声明。 它说要修改助手函数 user_ param 。 所以我把它添加到用户_ controller.rb 列表中 :

def user_params
  params.require(:user).permit(:name, :email, :password,
                             :password_confirmation, :admin)
end

下面,我把9.48中的代码抄录到插件/请求/用户_pages_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

测试然后失败, 显示可以通过一个管理参数, 从而将普通用户更改为管理参数, 这并不是您想要允许的 :

$ 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, 取消了第一个更改:

def user_params
  params.require(:user).permit(:name, :email, :password,
                             :password_confirmation)
end

现在试图用新的管理员值来修补用户失败... 而测试成功, 验证“ admin 属性不能通过网络编辑 ” 。

    $ rspec spec
...........................................................................................

Finished in 4.2 seconds
91 examples, 0 failures

在提示之后,我首先在 ap/models/user.rb 中将 < code>:admin 添加到 < code>, 添加到 app/ models/user.rb 中的 < code> 。

I then added the test:

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

红红的 红的 红的 红的 红的 红的 红的 红的 红的 红的 红的 红的 红的 红的 红的 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红 红

Removing :admin from user.rb I get a green. So far so good.

令我困惑的是,为什么我应该使用罪责:

@user.update_attributes(:admin => true)

而不是 (我检查过,在此情况下不起作用)。





相关问题
rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

SSL slowness in EC2

We ve deployed our rails app to EC2. In our setup, we have two proxies on small instances behind round-robin DNS. These run nginx load balancers for a dynamically growing and shrinking farm of web ...

Auth-code with A-Za-z0-9 to use in an URL parameter

As part of a web application I need an auth-code to pass as a URL parameter. I am currently using (in Rails) : Digest::SHA1.hexdigest((object_id + rand(255)).to_s) Which provides long strings like : ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

activerecord has_many :through find with one sql call

I have a these 3 models: class User < ActiveRecord::Base has_many :permissions, :dependent => :destroy has_many :roles, :through => :permissions end class Permission < ActiveRecord::...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签