【问题标题】:What's the right way to modify the params passed to controller in rails 3.1.0?在 rails 3.1.0 中修改传递给控制器​​的参数的正确方法是什么?
【发布时间】:2012-01-26 16:16:42
【问题描述】:

在我们的 Rails 3.1.0 应用程序中,我们需要修改在创建和更新中传递给 rfq 控制器的参数。比如我们要在input_by_id下记录当前用户id。我们所做的是:

  @rfq.input_by_id = session[:user_id]

它按预期工作。此外,当 need_report 字段为 false 时,report_language 字段应为 nil。我们决定在 rfq 控制器中添加以下行,以确保在 need_report 为 false 时将 nil 传递给 report_language:

  @rfq.report_language = nil unless params[:need_report]

但是,由于数据验证失败,此添加会导致 rspec 案例失败(在控制器的创建/更新中)。但是,当我们启动应用程序时,当 need_report 为 false 时,它​​不会保存 report_language 就可以正常运行。我想知道上面的行是否不是使用 params[:need_report] 进行@rfq 更新的正确方法。

非常感谢。

更新:

控制器代码:

  def create
    if has_create_right?
      @rfq = Rfq.new(params[:rfq], :as => :roles_new )
      @rfq.input_by_id = session[:user_id]
      #save sales_id selected
      if sales? && member? && !team_lead?
        @rfq.sales_id = session[:user_id]        
      end
      #view page may carry the hidden report language even if need_report == false
      @rfq.report_language = nil unless params[:need_report]
      #save into join table rfqs_standards
      params[:rfq][:standard_ids].each do |sid|  
        @rfq.standards << Standard.find(sid.to_i) if !sid.nil? && sid.to_i > 0 
      end unless params[:rfq][:standard_ids].nil?
      #save into join table rfqs_test_items
      params[:rfq][:test_item_ids].each do |tid|
        @rfq.test_items << TestItem.find(tid.to_i) if !tid.nil? && tid.to_i > 0 
      end unless params[:rfq][:test_item_ids].nil?
      if @rfq.save!
        redirect_to URI.escape("/view_handler?index=0&msg=RFQ saved!")
      else
        flash.now[:error] = "RFQ not saved!"
        render 'new'
      end
    else
       redirect_to URI.escape("/view_handler?index=0&msg=No rights!") 
    end
  end

添加@rfq.report_language = nil unless params[:need_report]后测试用例失败

   it "should be successful for corp head" do
      session[:corp_head] = true
      session[:user_id] = 1
      s = Factory(:standard)
      rfq = Factory.attributes_for(:rfq, :need_report => true, :report_language => 'EN')
      rfq[:standard_ids] = [s.id] # attach standard_id's to mimic the POST'ed form data
      get 'create', :rfq => rfq
      #response.should redirect_to URI.escape("/view_handler?index=0&msg=RFQ saved!")
      response.should render_template('new')
    end

【问题讨论】:

  • RSpec 测试究竟是如何失败的? “数据验证失败”有点含糊,无法提供帮助。你能发布你的一个测试的代码,以及来自那个控制器方法的代码吗?如果它在浏览器中运行良好,则可能意味着您的测试已损坏。
  • @rfq.report_language = nil unless params[:need_report] 相当于说 set @rfq.report_language to nil if params[:need_report] is nilfalse (如果对操作发出请求但未通过,则会发生这种情况该参数的值)。你说你不明白如何使用params 哈希;你想完成什么行为?
  • Batkins,你说的代码行是我的理解。但是,这行代码会导致要求选择语言的数据验证失败。在我们的测试中,在 Factory.attributes_for 中,need_report 设置为 true,report_language 设置为“EN”,这应该可以通过数据验证。 @rfq.report_language = nil 除非 params[:need_report] 不应该触发。我们不知道此案为何失败。

标签: ruby-on-rails rspec2 factory-bot


【解决方案1】:

问题在于您根本没有看到正确的值。

get 'create', :rfq =&gt; rfq 将产生类似{:rfq =&gt; {...}} 的参数哈希

所以你需要@rfq.report_language = nil unless params[:rfq][:need_report] == 'true'

【讨论】:

  • 我再次使用 params[:rfq][:need_report] 进行了测试。又一个 rspec 案例通过了。然而,当启动应用程序时,即使需要_report == false,report_language 也会被保存。似乎 params[:rfq][:need_report] 在需要时没有触发需要报告==假,因为它应该是。根据我的理解, params[:need_report] 应该返回 need_report 的值。
  • 那是因为你得到一个字符串而不是布尔值。如果您详细查看参数,您会看到"need_report" =&gt; "false"it's all strings!
  • 菲特,你是对的!我确实打印出 params[:rfq][:need_report] 和 params[:need_report]。 params[:rfq][:need_report] 打印出 true 或 false。然而 params[:need_report] 什么也没打印出来。我比较了 [:rfq][:prod_name] 和 [:prod_name] 结果是一样的。在控制器中的创建和更新中进行了测试。结论是从 params 中检索的正确方法是 params[:controller_name][:field_name]。 params[:field_name] 不是检索数据的正确方法。
猜你喜欢
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多