Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.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

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 Rails RSpec测试关联模型的补丁更新(通过web)_Ruby_Ruby On Rails 4_Patch_Rspec Rails_Model Associations - Fatal编程技术网

Ruby Rails RSpec测试关联模型的补丁更新(通过web)

Ruby Rails RSpec测试关联模型的补丁更新(通过web),ruby,ruby-on-rails-4,patch,rspec-rails,model-associations,Ruby,Ruby On Rails 4,Patch,Rspec Rails,Model Associations,我正在学习Michael Hartl Rails教程(使用Rails 4和RSpec Rails 3.3.3)并实现具有管理员权限的用户,这是通过向用户模型添加管理员布尔属性实现的。相反,我决定使用一个sperate管理模型(User有一个Admin;Admin属于User),它只存储用户id;如果表中存在一个用户id,那么它就是一个管理员(考虑到管理员与非管理员的预期比例,我觉得从长远来看,这会更有效) 建议进行用户控制器测试,以确保允许的参数不允许通过web像so一样编辑admin属性(用户

我正在学习Michael Hartl Rails教程(使用Rails 4和RSpec Rails 3.3.3)并实现具有管理员权限的用户,这是通过向用户模型添加管理员布尔属性实现的。相反,我决定使用一个sperate管理模型(User有一个Admin;Admin属于User),它只存储用户id;如果表中存在一个用户id,那么它就是一个管理员(考虑到管理员与非管理员的预期比例,我觉得从长远来看,这会更有效)

建议进行用户控制器测试,以确保允许的参数不允许通过web像so一样编辑admin属性(用户是使用Factory Girl在数据库中创建的):

为了测试我的版本,我尝试了以下RSpec测试:

context 'attempt to assign non-admin user as admin via update request via web' do
  it 'will not update admin status' do
    session[:user_id] = user.id # user is logged in as required to make patch request
    expect { patch :update, id: user, user: { name: user.name, email: user.email, admin: { user_id: user.id } } }.to change { Admin.count }.by 0
  end
end
该测试通过,但由于正确限制了允许的参数,因此未通过。为了检查反向操作是否有效,我想测试允许用户模型中的admin参数实际上会对admin表进行更改

我已更新用户控制器:

def user_params
  params.require(:user).permit(:name, :email, :password, :password_confirmation, admin: :user_id)
end
和用户\u控制器\u规格(按1检查管理员计数更改):

这会导致此错误(文档称,当分配给关联的对象的类型不正确时会引发此错误):

我有一种感觉,我可能完全误解了这一点:管理员模型应该直接更新,而不是通过用户模型更新,也许通过将管理员分离到一个单独的模型中,这样一个恶意的补丁请求给用户管理员状态甚至是不可能的(没有管理控制器或管理路由,因为我预计此类分配将在数据库级别进行;只有一个简单的管理模型,说明其属于与用户的关联)

考虑到我的情况,我真的很想得到一些关于是否应该写一个测试的建议


提前感谢。

顺便说一句,迈克尔·哈特尔是否没有自己的支持论坛和/或特定的标签

所以我得到了分支上的错误:

1) UsersController attempt to assign non-admin user as admin via update web request will update admin status
     Failure/Error: expect { patch :update, id: user, user: { name: user.name, email: user.email, admin: { user_id: user.id } } }.to change { Admin.count }.by 1
     ActiveRecord::AssociationTypeMismatch:
       Admin(#70235772428120) expected, got ActionController::Parameters(#70235708075860)
一个一般提示就是不要编写控制器规范…只喜欢特性和单元测试

下面是我如何剖析这个问题的

[tansaku@Samuels-MBP-2:~/Documents/Github/MakersAcademy/Students/April2015/AndyGout/theatrebase ((ac406cd...))]$ 
→ rspec ./spec/controllers/users_controller_spec.rb:89
Run options: include {:locations=>{"./spec/controllers/users_controller_spec.rb"=>[89]}}

UsersController
  attempt to assign non-admin user as admin via update web request

[29, 38] in /Users/tansaku/Documents/Github/MakersAcademy/Students/April2015/AndyGout/theatrebase/app/controllers/users_controller.rb
   29:     @page_title = @user.name
   30:   end
   31: 
   32:   def update
   33:     require 'byebug' ; byebug
=> 34:     if @user.update_attributes(user_params)
   35:       flash[:success] = "Profile updated successfully: #{@user.name}"
   36:       redirect_to @user
   37:     else
   38:       @page_title = User.find(params[:id]).name
(byebug) @user
#<User:0x007fede0b81b60>
(byebug) user_params
{"name"=>"Andy Gout", "email"=>"andygout@example.com", "admin"=>{"user_id"=>"1"}}
[tansaku@Samuels-MBP-2:~/Documents/Github/makerscademy/Students/April2015/AndyGout/theaterbase((ac406cd…))$
→ rspec./spec/controllers/users\u controller\u spec.rb:89
运行选项:包括{:位置=>{../spec/controllers/users\u controller\u spec.rb=>[89]}
用户控制器
尝试通过更新web请求将非管理员用户分配为管理员
[29,38]in/Users/tansaku/Documents/Github/makerscademy/Students/April2015/AndyGout/theratebase/app/controllers/Users\u controller.rb
29:@page_title=@user.name
30:完
31: 
32:def更新
33:需要“byebug”;byebug
=>34:if@user.update_属性(用户参数)
35:flash[:success]=“配置文件已成功更新:#{@user.name}”
36:将_重定向到@user
37:其他
38:@page_title=User.find(params[:id]).name
(byebug)@user
#
(byebug)用户参数
{“姓名”=>“安迪·古特”,“电子邮件”=>“andygout@example.com“,“管理员”=>{“用户id”=>“1”}”
我认为这里的问题似乎不是通过简单的params散列创建新的admin对象

我认为有两个办法

  • 操纵参数以插入新的管理对象
  • 使用接受\u嵌套的\u属性\u

  • 顺便问一下,迈克尔·哈特尔是否没有自己的支持论坛和/或特定的标签

    所以我得到了分支上的错误:

    1) UsersController attempt to assign non-admin user as admin via update web request will update admin status
         Failure/Error: expect { patch :update, id: user, user: { name: user.name, email: user.email, admin: { user_id: user.id } } }.to change { Admin.count }.by 1
         ActiveRecord::AssociationTypeMismatch:
           Admin(#70235772428120) expected, got ActionController::Parameters(#70235708075860)
    
    一个一般提示就是不要编写控制器规范…只喜欢特性和单元测试

    下面是我如何剖析这个问题的

    [tansaku@Samuels-MBP-2:~/Documents/Github/MakersAcademy/Students/April2015/AndyGout/theatrebase ((ac406cd...))]$ 
    → rspec ./spec/controllers/users_controller_spec.rb:89
    Run options: include {:locations=>{"./spec/controllers/users_controller_spec.rb"=>[89]}}
    
    UsersController
      attempt to assign non-admin user as admin via update web request
    
    [29, 38] in /Users/tansaku/Documents/Github/MakersAcademy/Students/April2015/AndyGout/theatrebase/app/controllers/users_controller.rb
       29:     @page_title = @user.name
       30:   end
       31: 
       32:   def update
       33:     require 'byebug' ; byebug
    => 34:     if @user.update_attributes(user_params)
       35:       flash[:success] = "Profile updated successfully: #{@user.name}"
       36:       redirect_to @user
       37:     else
       38:       @page_title = User.find(params[:id]).name
    (byebug) @user
    #<User:0x007fede0b81b60>
    (byebug) user_params
    {"name"=>"Andy Gout", "email"=>"andygout@example.com", "admin"=>{"user_id"=>"1"}}
    
    [tansaku@Samuels-MBP-2:~/Documents/Github/makerscademy/Students/April2015/AndyGout/theaterbase((ac406cd…))$
    → rspec./spec/controllers/users\u controller\u spec.rb:89
    运行选项:包括{:位置=>{../spec/controllers/users\u controller\u spec.rb=>[89]}
    用户控制器
    尝试通过更新web请求将非管理员用户分配为管理员
    [29,38]in/Users/tansaku/Documents/Github/makerscademy/Students/April2015/AndyGout/theratebase/app/controllers/Users\u controller.rb
    29:@page_title=@user.name
    30:完
    31: 
    32:def更新
    33:需要“byebug”;byebug
    =>34:if@user.update_属性(用户参数)
    35:flash[:success]=“配置文件已成功更新:#{@user.name}”
    36:将_重定向到@user
    37:其他
    38:@page_title=User.find(params[:id]).name
    (byebug)@user
    #
    (byebug)用户参数
    {“姓名”=>“安迪·古特”,“电子邮件”=>“andygout@example.com“,“管理员”=>{“用户id”=>“1”}”
    
    我认为这里的问题似乎不是通过简单的params散列创建新的admin对象

    我认为有两个办法

  • 操纵参数以插入新的管理对象
  • 使用接受\u嵌套的\u属性\u
  • 谢谢@SamJoseph

    我还将检查Hartl的支持情况(尽管我意识到我偏离了他的指导…)

    第二个建议帮助我找到了解决方案,使用了以下更改:-

    用户(用户模型):

    accepts_nested_attributes_for :admin
    
    def user_params
      params.require(:user).permit( :name,
                                    :email,
                                    :password,
                                    :password_confirmation,
                                    admin_attributes: :user_id
                                  )
    end
    
      context 'attempt to assign non-admin user as admin via update web request' do
        it 'will update admin status' do
          session[:user_id] = user.id
          expect { patch :update, id: user, user: { name: user.name, email: user.email, admin_attributes: { user_id: user.id } } }.to change { Admin.count }.by 1
        end
      end
    
    用户\u控制器:

    accepts_nested_attributes_for :admin
    
    def user_params
      params.require(:user).permit( :name,
                                    :email,
                                    :password,
                                    :password_confirmation,
                                    admin_attributes: :user_id
                                  )
    end
    
      context 'attempt to assign non-admin user as admin via update web request' do
        it 'will update admin status' do
          session[:user_id] = user.id
          expect { patch :update, id: user, user: { name: user.name, email: user.email, admin_attributes: { user_id: user.id } } }.to change { Admin.count }.by 1
        end
      end
    
    用户\u控制器\u规格:

    accepts_nested_attributes_for :admin
    
    def user_params
      params.require(:user).permit( :name,
                                    :email,
                                    :password,
                                    :password_confirmation,
                                    admin_attributes: :user_id
                                  )
    end
    
      context 'attempt to assign non-admin user as admin via update web request' do
        it 'will update admin status' do
          session[:user_id] = user.id
          expect { patch :update, id: user, user: { name: user.name, email: user.email, admin_attributes: { user_id: user.id } } }.to change { Admin.count }.by 1
        end
      end
    
    这通过了测试,因此我现在可以自信地从这一点开始,按照我的要求测试反向

    它非常有用,
    接受
    的_嵌套的_属性_是我不久将再次需要的东西

    我对你在第一个建议中的意思有点不确定:操纵参数以插入一个新的管理对象-这是否以某种方式在参数中添加一个命令以直接在数据库中创建一个新的管理条目(或类似的内容)?我将进一步调查

    我能不能也检查一下不写控制器规格:鉴于这似乎是一个重要的测试,写一个功能规格来提出这个直接的补丁请求会更好?你有什么建议