在轨道3中将逻辑从控制器移动到模型?

时间:2011-01-27 15:09:03

标签: ruby-on-rails ruby ruby-on-rails-3

我一直在构建一个竞赛应用程序,我可以很容易地告诉我,我已经在控制器中添加了太多逻辑。如何将此类逻辑切换到模型? (这里重要的不是逻辑本身 - 它远未完成 - 我只是想了解如何将其移出控制器)。

控制器:

def create
    @person = Person.new(params[:person])
    @yournum = rand(100)
    @day = Day.find_by_id(1)
    @prereg = Prereg.find_by_email(@person.email)

    if @preg != nil
      @person.last_name = @prereg.name
    end 

    if @day.number == 1


      if @yournum <= 25
      @person.prize_id = 2
      elsif @yournum > 25 && @yournum <=50
      @person.prize_id = 1
      elsif @yournum > 51 && @yournum <=75
      @person.prize_id = 3
      elsif @yournum > 76 && @yournum <=100
      @person.prize_id = 4
      end

    elsif @day.number == 2

      if @yournum <= 25
      @person.prize_id = 2
      elsif @yournum > 25 && @yournum <=50
      @person.prize_id = 1
      elsif @yournum > 51 && @yournum <=75
      @person.prize_id = 3
      elsif @yournum > 76 && @yournum <=100
      @person.prize_id = 4
      end

    elsif @day.number == 3      

      if @yournum <= 50
      @person.prize_id = 2
      elsif @yournum > 51 && @yournum <=90
      @person.prize_id = 1
      elsif @yournum > 91 && @yournum <= 95
      @person.prize_id = 3
      elsif @yournum > 96 && @yournum <=100
      @person.prize_id = 4
      end

    end

    @person.save
    redirect_to @person

  end

型号:

class Person < ActiveRecord::Base
  belongs_to :prize

end

谢谢!

埃利奥特

2 个答案:

答案 0 :(得分:3)

确实,这是一个非常难看的控制器。正如您所说,解决方案很简单:将所有逻辑移至模型:

def create
  @person = Person.new(params[:person])
  @person.set_price

  if @person.save
    redirect_to @person
  else
    flash[:error] = ...
    render :action => 'new'
  end
end

class Person
  def set_price
    # your logic here
  end
end    

请注意:

  1. 控制器:您需要检查实际是否已保存@person(可能是某些验证失败)。
  2. 型号:如果始终在创建时为某人分配价格,则使用回调(例如before_validation)。否则,请从控制器中调用它,如上面的代码所示。

答案 1 :(得分:1)

class PersonsController < ApplicationController
  respond_to :html
  def create
    @person = Person.new(params[:person])

    if @person.save
      respond_with @person
    else
      flash[:error] = 'Render error'
      render :action => :new
    end
  end
end

class Person
  before_create :method_name

  def method_name
    #Put whatever you want to happen before creation here
  end
end