Forum: Ruby on Rails How to pass a variable from a model method to a controller

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Tom H. (Guest)
on 2009-04-25 14:30
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
7stud -. (Guest)
on 2009-04-25 17:32
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.


2) 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
Tom H. (Guest)
on 2009-04-25 19:26
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 !
Chris K. (Guest)
on 2009-04-27 10:49
(Received via mailing list)
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
Tom H. (Guest)
on 2009-04-27 11:23
Thanks! Always good to get some critical remarks & advice...
7stud -. (Guest)
on 2009-04-27 12:34
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?
This topic is locked and can not be replied to.