2

采取以下代码:

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

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

4

3 回答 3

2

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

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

于 2011-03-09T14:23:25.390 回答
1

不,这是公认的模式。它通常像这样使用,内置 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 保护)。

于 2011-03-09T13:56:21.080 回答
0

如果我猜对了,当你有不同的情况时,你有一些想要执行的操作accept,如果 accept 是假的,shots应该challenge_msg是 nil

这可以通过几种方式完成

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

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

if params[:challenge][:accepted] == "0"
  params[:challenge][:shots]         = nil
  params[:challenge][:challenge_msg] = nil
end

@challenge.update_attributes(params[:challenge])

或者在模型中,您可以使用 before_save 之类的回调来设置shotschallenge_msg在保存之前设置为 nil if acceptis false

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

于 2011-03-09T14:17:12.163 回答