Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails moving controller logic into model

I'm in the process of refactoring for my rails application. I've read many posts about moving controller logic to models, but I encountered some problems when I tried.

I need help to

  1. Understand the reasons for the following errors
  2. Need to know what documents I should read to successfully move all my controller logic to model

As I hadn't done any major refactoring for my application yet, tried a simple one first.

PostsController(before)

def create
    @post = Post.create(params[:post])
    @post.user_id = session[:user_id]
    @post.num_likes = 0
    @post.num_dislikes = 0
    @geoip = GeoIP.new("#{Rails.root.to_s}/db/GeoIP.dat").country(request.remote_ip)
    @post.user_location = @geoip.country_name
end

PostModel(new)

before_save :initialize_post

def initialize_post
    self.user_id = session[:user_id]
    self.num_likes = 0
    self.num_dislikes = 0
    @geoip = GeoIP.new("#{Rails.root.to_s}/db/GeoIP.dat").country(request.remote_ip)
    self.user_location = @geoip.country_name
end

PostsController(new)

def create
    @post = Post.create(params[:post])
end

However, I failed to do even this simple refactoring because of such errors as session undefined AND method request undefined. I'm not sure why these actions cant be used in the model class.

Could someone explain the reason behind this and direct me to some good documentation that will help me go through a smooth refactoring process?

Thanks a lot.

like image 920
Maximus S Avatar asked Aug 28 '26 03:08

Maximus S


2 Answers

For your controller I'd do something like..

def create
    @post = Post.new(params[:post])
    @post.user_id = session[:user_id]
    @post.ip_address = request.remote_ip
    @post.save
end

and your model .. something like;

attr_accessor :ip_address
before_create :set_default_values
before_save :geo_locate

private

def geo_locate
    @geoip = GeoIP.new("#{Rails.root.to_s}/db/GeoIP.dat").country(self.ip_address) rescue nil
    self.user_location = @geoip.country_name unless @geoip.blank?
end

# This only runs when a new record is created. Alternatively, look into setting a default value on your database columns!
def set_default_values
  self.num_likes = 0
  self.num_dislikes = 0
end
like image 166
Jamsi Avatar answered Aug 29 '26 18:08

Jamsi


You can't move every code in the controller to model. Some code like session handling and request are only scoped to controller. They are not available inside model. Only processing code that is only restricted to model level processing need to be in model.

Following is best book to refactor the rails code,

http://www.amazon.com/Rails-AntiPatterns-Refactoring-Addison-Wesley-Professional/dp/0321604814

like image 22
maximus ツ Avatar answered Aug 29 '26 18:08

maximus ツ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!