How to pass a variable from a model method to a controller


#1

Hi there,

how can I pass a variable from a model method to the controller that
calls this method?

In the below code, I tried by placing “return @errormessage” in the
model method and then trying to retrieve it in the controller, but it’s
wrong. What’s the correct way to do that?

Here’s what it looks like until now (simplified)…

In my controller:

def whatever
if @user.does_my_check_pass? # <= calls the model method
below…
[…]
else
flash.now[:error] = @errormessage # <= the variable from the
method
render :update do |page|
page.replace_html ‘flash_messages’, flash_messages
end
end
end

In my model:

def does_my_check_pass?
if […some conditions…]
return true
else
return @errormessage = “There was an error.” # <= the variable
return false
end
end

Thanks a lot for your help!
Tom


#2

Tom Ha wrote:

Hi there,

how can I pass a variable from a model method to the controller that
calls this method?

In the below code, I tried by placing “return @errormessage” in the
model method and then trying to retrieve it in the controller, but it’s
wrong. What’s the correct way to do that?

Here’s what it looks like until now (simplified)…

In my controller:

def whatever
if @user.does_my_check_pass? # <= calls the model method
below…
[…]
else
flash.now[:error] = @errormessage # <= the variable from the
method
render :update do |page|
page.replace_html ‘flash_messages’, flash_messages
end
end
end

In my model:

def does_my_check_pass?
if […some conditions…]
return true
else
return @errormessage = “There was an error.” # <= the variable
return false
end
end

Thanks a lot for your help!
Tom

How about

In my model:

def does_my_check_pass?
if […some conditions…]
return true
else
return “There was an error.”
end
end

In my controller:

def whatever
if (result = @user.does_my_check_pass) == true
[…]
else
flash.now[:error] = result

  1. Note that both a string and true evaluate to true in an if
    statement, so you couldn’t write:

if (result = @user.does_my_check_pass)

The condition would always evaluate to true.

  1. Experienced ruby programmers would not write “return”:

In my model:

def does_my_check_pass?
if […some conditions…]
true
else
“There was an error.”
end
end


#3

You got that right, I’m not (yet) an experienced ruby programmer, but
you’ve just helped me to get a step further - so thanks a lot, bro !


#4

Thanks! Always good to get some critical remarks & advice…


#5

Not 100% sure I understand what you’re trying to do, but here are a
couple
of items that strike me based on the code posted.

First, your model method has two return statements. I don’t know
whether
Ruby will throw up some kind of parsing error to that, but certainly the
second of those will never be executed.

Second, putting error message text in the model is probably not what you
want to be doing. Your error messages are not part of your business
logic.
Most people put these things in the controller, although strictly
speaking,
they probably belong in the view (though Rails doesn’t make it very easy
to
put them there and keep your code looking good).

Finally, I assume your controller is taking in some input as HTTP
request
params before it runs this “does_my_check_pass?” method. If so, then I
guess your check should actually be a part of the standard ActiveRecord
validation process. In that case, inputs will be checked every time you
create or update a new User object rather than in any case you remember
to
call it. The proper flow control through the controller action should
be
pretty standard: rececive inputs, delegate validation to the model,
perform
necessary model operations (CRUD), and render/redirect user output.

Hope that is helpful to you.

On Sat, Apr 25, 2009 at 12:30 PM, Tom Ha


#6

Chris K. wrote:

Second, putting error message text in the model is probably not what you
want to be doing. Your error messages are not part of your business
logic.
Most people put these things in the controller, although strictly
speaking,
they probably belong in the view (though Rails doesn’t make it very easy
to
put them there and keep your code looking good).

I’m reading AWDWR(3rd.) and in the first full example, which is a
shopping cart, there is a user interface with CRUD operations for
entering new Product’s in the database. The example uses method calls
to standard rails validation methods in the model, for example:

validates_presence_of :description

as well as a custom validation method:

  validate :price_must_be_at_least_a_cent

protected
  def price_must_be_at_least_a_cent
    if price.nil? || price < .01
      errors.add(:price, 'should be at least .01')
    end
  end

That has an error message in the model, which seems contrary to your
advice. Also, at the start of the section on validation, the authors
say:


So, where to put the validation? The model layer is the gatekeeper
between the world of code and the database. Nothing to do with our
application comes out of the database or gets stored in the database
that doesn’t first go through the model. This makes models an ideal
place to put validation;…

If you have several controllers all accessing the database through the
same model, then wouldn’t you “get wet” duplicating the validation in
each controller?