Andreas Lyngstad
Andreas Lyngstad

Reputation: 4927

Setting nested attributes in the model rails

I have a Log model that belongs to User and Firm. For setting this I have this code in the logs_controller's create action.

 def create
     @log = Log.new(params[:log])
     @log.user = current_user
     @log.firm = current_firm
     @log.save
   end

current_user and current_firm are helper methods from the application_helper.rb

While this works it makes the controller fat. How can I move this to the model?

Upvotes: 0

Views: 96

Answers (3)

Unixmonkey
Unixmonkey

Reputation: 18794

Not much shorter, but the responsibility for the handling of current_user falls to the controller in MVC

def create
 @log = Log.create(params[:log].merge(
   :user => current_user,
   :firm => current_firm))
end

EDIT

If you don't mind violating MVC a bit, here's a way to do it:

# application_controller.rb
before_filter :set_current
def set_current
  User.current = current_user
  Firm.current = current_firm
end

# app/models/user.rb
cattr_accessor :current

# app/models/firm.rb
cattr_accessor :current

# app/models/log.rb
before_save :set_current
def set_current
  self.firm = Firm.current
  self.user = User.current
end

# app/controllers/log_controller.rb
def create
  @log = Log.create(params[:log])
end

Upvotes: 0

deefour
deefour

Reputation: 35370

I believe this sort of functionality belongs in a 'worker' class in lib/. My action method might look like

def create
  @log = LogWorker.create(params[:log], current_user, current_firm)
end

And then I'd have a module in lib/log_worker.rb like

module LogWorker
  extend self

  def create(params, user, firm)
    log      = Log.new(params)
    log.user = user
    log.firm = firm

    log.save
  end
end

This is a simplified example; I typically namespace everything, so my method might actually be in MyApp::Log::Manager.create(...)

Upvotes: 3

Valery Kvon
Valery Kvon

Reputation: 4496

No difference: You can refactor the code:

def create
  @log = Log.new(params[:log].merge(:user => current_user, :firm => current_firm)
  @log.save
end

And your Log have to:

attr_accessible :user, :firm

Upvotes: 0

Related Questions