2

私はMichaelHartlのRailsチュートリアルに取り組んでいます。第9章、演習1に来ました。クラスのadmin属性にアクセスできないことを確認するためのテストを追加するように求められます。User無関係な部分がコメントアウトされたUserクラスは次のとおりです。

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

  # before_save methods
  # validations
  # private methods
end

adminこれが、属性にアクセスできないことを検証するために使用しているテストです。

describe User do
  before do
    @user = User.new( 
                     name: "Example User",
                     email: "user@example.com",
                     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

テストは失敗します。admin属性が保護されているにもかかわらず、エラーは発生しなかったと表示されます。どうすればテストに合格できますか?

4

6 に答える 6

5

Rubyのドキュメントから:

一括割り当てセキュリティは、エンドユーザーの割り当てから属性を保護するためのインターフェイスを提供します。

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

代わりにこのコードを試してください

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
于 2012-05-26T20:14:47.500 に答える
3

Railsのドキュメントがattr_protectedについて主張しているように

このマクロで指定された属性は、new(attributes)、update_attributes(attributes)、attributes =(attributes)などの一括割り当てから保護されます。

したがって、フィールドを手動で変更できます。'attr_protected'は、一括割り当てに関するものです。

于 2012-05-25T05:16:48.000 に答える
1

これは、フォーム送信からのフィールドの設定などの一括割り当てでのみ機能します。次のようなものを試してください。

@user.update_attrtibutes(:admin => true)
@user.admin.should be_false
于 2012-05-25T05:16:45.777 に答える
1

@agaved。この答えは遅れるかもしれませんし、あなたはすでに答えを持っているかもしれませんが、私はあなたの質問に答えたかったのです、それは他の誰かを助けるかもしれません。

update_attributes直接割り当てとの違いを理解する最良の方法
@user.admin = trueは、コンソールで試してみることです。Hartlのチュートリアルに従っている場合は、次のことを試してください。

@user = User.first
@user.admin?
=> true
@user.admin = false
=> false

直接割り当ては、一括割り当てエラーを発生させることなくtrue、ユーザーの属性adminの値をからに変更することができます。falseこれは、アクセスできない属性を使用しupdate_attributesて新しいユーザーを呼び出すか作成すると、一括割り当てエラーが発生するためです。User.new言い換えると、Railsは、ユーザーがアクセスできない属性を使用して新しいユーザーを更新(attribute_update)または作成しようとすると、一括割り当てエラーを発生させます。User.new(admin: true)上記の場合、直接割り当てでは、ユーザーコントローラーのcreateメソッドまたはupdateメソッドは使用されません。

上記の場合、IRBで直接使用して、直接割り当てを使用してadmin属性を強制的に変更できるため、これらは非常によく似たコードですが、前述のように、@user.save!(validate: false)これはユーザーコントローラーのcreateまたはupdateメソッドを使用しないためです。 、エラーはスローされません。

それがお役に立てば幸いです、これは私を助けました。

于 2013-07-10T03:27:15.860 に答える
1

[ネタバレ注意:Hartlの本の演習を自分で解決しようとしているのなら、私は答えを出そうとしていると確信しています。受け入れられた答えは興味深い情報ですが、それは本がカバーしていない知識を必要とし、Webアクションによる更新やテストの使用に特に関連していないため、Hartlが念頭に置いていたものではないと思います彼は提供します。]

私が正しく理解すれば、この演習は実際よりもはるかに難しいと思われるかもしれません。まず第一に、あなたはヒントを誤解しました:

ヒント:最初のステップは、user_paramsの許可されたパラメーターのリストにadminを追加することです。

クラス内の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_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

その後、テストは失敗し、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 

次に、Webアクションを介してadmin値を渡せないようにするために、受け入れ可能なuser_paramsのリストから:adminを削除し、最初の変更を元に戻しました。

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

これで、新しいadmin値でユーザーにパッチを適用する試みは失敗し、そのテストは成功し、「admin属性がWebで編集できないこと」を確認します。

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

Finished in 4.2 seconds
91 examples, 0 failures
于 2014-07-22T00:02:10.580 に答える
0

ヒントに従って、最初にapp / models/user.rbに追加:adminして赤で開始しました。attr_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

スペックに合わせて赤になりました。

:adminuser.rbから削除すると、緑色になります 。ここまでは順調ですね。

私を困惑させるのは、なぜ私がsintaxを使うべきなのかということです。

@user.update_attributes(:admin => true)

代わりに@user.admin = true(私はチェックしましたが、この場合は機能しません)。

于 2012-11-16T14:22:24.047 に答える