0

I have a checkbox that if checked allows my child resource called Engineer to be created. I'm trying to create it through my model since that's where I can call the after_save method.

Here is my code:

models/user.rb

class User < ActiveRecord::Base
  has_many :armies
  has_many :engineers  
end

models/army.rb

class Army < ActiveRecord::Base
 has_many :engineers
 attr_reader :siege
 after_save :if_siege
 private

 def if_siege
   if self.siege
    Engineer.create!( :user_id => current_user.id, :army_id => self.id )
   end
 end
end

models/engineer.rb

class Engineer < ActiveRecord::Base
  belongs_to :user
  belongs_to :army
end

controllers/armies_controller.rb

def new
  @army = Army.new
end

def create
  @army = current_user.armies.build(params[:army])
    if @army.save
      redirect_to new_army_path
    else
      render :new
    end
  end
end

This gives me an error though for my if_siege method:

undefined local variable or method `current_user'

How can I fix this or is there another way to do this? Not sure if this should go in the controller or model but I only can wrap my head around putting this in the model.

Thanks.

LearningRoR
  • 26,582
  • 22
  • 85
  • 150

2 Answers2

1

Add belongs_to :user to the Army model

In Army#if_siege, update Engineer.create! as follows

Engineer.create!( :user_id => self.user.id, :army_id => self.id )
Hoa
  • 3,179
  • 1
  • 25
  • 33
1

First, the current_user object won't exist within the context of the Model layer unless your authentication is doing something to make it available. This is usually a non Threadsafe approach though. Maybe for you this isn't the issue.

Current User Instantiation

Having said that, one way (perhaps not the ideal way) to address this is by creating an attr_accessor in the model on the object called Army. Then set the current_user to this in the Army new action in the controller where the current_user instance is available.

# in the Army model
attr_accessor :the_user

# in the Army Controller
@army = Army.new(:the_user => current_user.id)

You will also have to add a hidden field to store this value in your view to carry this through to the create action.

Just an observation, but I'm fairly sure in the "if_seige" method the self calls are redundant. self should already be scoped to the Army object in that method.

Community
  • 1
  • 1
engineerDave
  • 3,887
  • 26
  • 28