【问题标题】:Model aware of params hash - Rails anti-pattern?模型知道参数哈希 - Rails 反模式?
【发布时间】:2011-03-09 13:03:11
【问题描述】:

取以下代码:

class ChallengesController < ApplicationController

  def update
    @challenge = Challenge.find(params[:id])
    @challenge.update!(params[:challenge]) # never an expected error, show error page and give hoptoad notification

    respond_to do |format|
      format.html { redirect_to :action => 'index' }
    end
  end

end

class Challenge < ActiveRecord::Base

  def update!(options)
    if options[:accept] == '1' then
      self.accepted = true
      self.response_at = Time.now        
      self.shots = options[:shots] unless options[:shots].blank?             
      self.challengee_msg = options[:challengee_msg] unless options[:challengee_msg].blank?
    else
      self.accepted = false
      self.response_at = Time.now
    end
  end

end

模型知道传递给它的参数哈希是否被认为是不好的做法?如果是这样,您将如何重构以使其遵循“最佳实践”?

【问题讨论】:

    标签: ruby-on-rails model controller convention


    【解决方案1】:

    有一件事是,如果您将参数传递到模型中并对其进行处理,请采用先执行 .dup 的做法。没有什么比试图找出路由混乱的原因更令人沮丧的了,只是发现某处的模型一直在从 params 哈希中删除键。

    此外,如果您出于任何原因将参数哈希传递到模型中,请确保在该模型上具有 attr_accessible。您需要将参数视为未经处理的用户输入。

    【讨论】:

      【解决方案2】:

      不,这是公认的模式。它通常像这样使用,内置 active_record 方法 update_attributes。

      @challenge = Challenge.find(params[:id])
      if @challenge.update_attributes(params[:challenge])
        flash[:success] = "Challenge updated"
        redirect_to @challenge
      else
        render :action=>:edit
      end
      

      这将采用哈希值并自动设置您发送的属性(除非它们受 attr_protected 保护)。

      【讨论】:

      • 为了清楚起见,您不需要实现 update_attributes -- 该方法已经为您存在。
      【解决方案3】:

      如果我猜对了,当你对accept 有不同的情况时,你有一些想要执行的操作,如果接受为假,shotschallenge_msg 应该为零

      这可以通过几种方式完成

      要在视图中执行此操作,可能使用一些 javascript 脚本,您可以清除和隐藏 shotschallenge_msg 的字段并相应地提交表单

      或者在控制器中,您必须通过执行以下操作将 shotschallenge_msg 设置为 nil:

      if params[:challenge][:accepted] == "0"
        params[:challenge][:shots]         = nil
        params[:challenge][:challenge_msg] = nil
      end
      
      @challenge.update_attributes(params[:challenge])
      

      或者在模型中,如果 accept 为 false,您可以使用 before_save 之类的回调将 shotschallenge_msg 设置为 nil,然后再保存

      只是一些改进代码的建议,希望对您有所帮助 =)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-11
        • 2019-06-30
        • 2013-09-10
        • 1970-01-01
        • 2013-10-10
        • 1970-01-01
        • 2011-03-08
        相关资源
        最近更新 更多