Moving logic from controller to model in rails 3?
I've been building a contest ap开发者_高级运维plication, and I can easily tell I've been putting wayyyy too much logic in the controller. How can I go about switch this type of logic to the model? (whats important here isn't the logic itself - its far from finished - I'm just trying to understand how to move it out of the controller).
Controller:
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
Model:
class Person < ActiveRecord::Base
belongs_to :prize
end
Thanks!
Elliot
Indeed, that's a pretty ugly controller. As you say, the solution is easy: move all the logic to the model:
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
Note that:
- Controller: you need to check if
@person
was actually saved (maybe some validation failed). - Model: If a person has always to be assigned a price on creation, then use a callback (
before_validation
, for example). Otherwise, call it from the controller as shown the code above.
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
精彩评论