views:

55

answers:

3

Is there a way to check which controller method was called from within the model?

Example: Say the controller create method was called:

def create
     do something
end

Then in the model do something only when create in the controller was called

if create?
      do something
end
+2  A: 

I'd imagine you could examine the call stack but this is exactly what models are not for: they should now nothing about the controller.

Examining the stack:

if caller.grep /create/
  # do something
elsif caller.grep /update/
  #do something else
end

Should do the trick.

Jakub Hampl
this is a special case. sometimes you need to see what method it came from. for instance in the validation methods there an :on => :create symbol
bandhunt
In that case just use the `caller` method that returns an array of method names called.
Jakub Hampl
On the one hand it is nice to know something like this is possible. But this feels wrong to me like @Jakub said: this is not what models are for. And a model can know if you are creating a new object or updating an existing object. If there is a need for this, i would add a parameters to my initialize or something. To keep the model as ignorant and seperate as possible (not to mention testable: how will you test such behaviour?).
nathanvda
@Jakub: what if there's a method called `create` or `update` in the call stack other than the controller method?
Alex - Aotea Studios
@Alex well then you should just adjust the code. I provided this more as an example of how to do it. The `caller` method gives also file names so you could check that the method originated from the right file for example. And as I said, you shouldn't be doing this in the first place.
Jakub Hampl
+2  A: 

Just pass a create flag to the model method, or make two different methods in the model and call the appropriate one from the controller. Otherwise you are creating a rather unpleasant dependency between the controller and the model. As you noted, validation methods take a parameter to specify when they are run.

Alex - Aotea Studios
+1  A: 

Inside your model you can ask/know if the record you are handling is a new record or not

p = Post.new
p.new_record? => true
p = Post.first
p.new_record? => false

maybe that helps you enough?

Otherwise inside a model you can add callbacks, e.g. a before_create that is only called before a new record is saved. To keep your model lean, and you should have a lot of callbacks, those could be grouped inside an observer.

Hope this helps.

nathanvda