Модель знает о хэше params - Rails anti-pattern? - PullRequest
2 голосов
/ 09 марта 2011

Возьмите следующий код:

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

Считается ли плохой практикой, чтобы модель знала, что ей передается хэш параметров? Если да, то как бы вы осуществили рефакторинг, чтобы он соответствовал «лучшей практике»?

Ответы [ 3 ]

2 голосов
/ 09 марта 2011

Во-первых, если вы передаете параметры в свою модель и копаетесь в ней, сначала примените практику создания .dup.Нет ничего более расстраивающего, чем пытаться выяснить, почему маршрутизация испорчена, только чтобы найти модель, где-то удалял ключи из хэша params.

Кроме того, если вы передаете хэш params в модельпо любой причине, убедитесь, что в этой модели есть attr_accessible.Вам нужно обрабатывать params как необработанный ввод данных пользователем.

1 голос
/ 09 марта 2011

Нет, это принятый шаблон.Обычно он используется так со встроенным методом 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).

0 голосов
/ 09 марта 2011

если я правильно угадал, у вас есть определенные действия, которые вы хотите выполнить, когда у вас есть другой случай для accept, и если accept ложна, shots и challenge_msg должны быть nil

это можно сделать несколькими способами

чтобы сделать это в представлениях, возможно, с помощью некоторых сценариев JavaScript, вы можете очистить и скрыть поля для shots и challenge_msg и отправить форму соответственно

или в контроллере, вам придется установить shots и challenge_msg на ноль, выполнив что-то вроде:

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

@challenge.update_attributes(params[:challenge])

или в модели, вы можете сделать это с помощью обратных вызовов, таких как before_save, чтобы установить shots и challenge_msg в ноль перед сохранением, если accept равно false

просто несколько предложений по улучшению вашего кода, надеюсь, это поможет =)

...