show method variable

30 views
Skip to first unread message

Joe Guerra

unread,
Mar 2, 2017, 11:07:06 AM3/2/17
to Ruby on Rails: Talk
In my show method for my products controller I've got a variable that track qty ( @remaining ).

Can I access this variable from another method within the same controller?

Thanks,
Joe

tamouse pontiki

unread,
Mar 2, 2017, 11:15:20 AM3/2/17
to rubyonra...@googlegroups.com
On Thu, Mar 2, 2017 at 10:07 AM Joe Guerra <JGu...@jginfosys.com> wrote:
In my show method for my products controller I've got a variable that track qty ( @remaining ).

Can I access this variable from another method within the same controller?


Joe,

You *can* as it is an *instance variable*, but it will only be available for that instance of the controller (i.e., a single request). If you're calling other methods during that show request, the instance variable will be available. If you want to access it from another method that responds to a different request, it won't be set. You can also use this instance variable in any views resulting from the show method.

I hope this was clear enough...

Tamara

Joe Guerra

unread,
Mar 2, 2017, 11:29:45 AM3/2/17
to Ruby on Rails: Talk
ok good.  yes, I will call it from within that same controller..

Now I've got to figure out how to run an update query.

Joe Guerra

unread,
Mar 3, 2017, 12:34:01 PM3/3/17
to Ruby on Rails: Talk
ok, I added this piece of code...


  if @remaining == 1
# put some conditions around this @remaining == 0?
  Product.update(params[:product_id], :funded => true)
 
Cart.where(:product_id => params[:product_id]).update_all(:processing => true)
 
#
  end

in my add to cart method, where @remaining was defined in my show section.  It's not running in this cart method when the condition is met.

I can try outputting the value, and see what I get.



On Thursday, March 2, 2017 at 11:15:20 AM UTC-5, tamouse wrote:

Joe Guerra

unread,
Mar 3, 2017, 12:51:29 PM3/3/17
to Ruby on Rails: Talk
ok, i used pry.binding to look at the @remining variable and it's nil.

that why it's not working.    so the question is why is this the case when it has a value in the show section?

Colin Law

unread,
Mar 3, 2017, 1:21:17 PM3/3/17
to Ruby on Rails: Talk
On 3 March 2017 at 17:51, Joe Guerra <JGu...@jginfosys.com> wrote:
> ok, i used pry.binding to look at the @remining variable and it's nil.
>
> that why it's not working. so the question is why is this the case when
> it has a value in the show section?

As tamouse said:
>>> You *can* as it is an *instance variable*, but it will only be available
>>> for that instance of the controller (i.e., a single request). If you're
>>> calling other methods during that show request, the instance variable will
>>> be available. If you want to access it from another method that responds to
>>> a different request, it won't be set. You can also use this instance
>>> variable in any views resulting from the show method.

You are trying to access it from another method that responds to a
different request.

Colin

Joe Guerra

unread,
Mar 3, 2017, 5:03:55 PM3/3/17
to Ruby on Rails: Talk
Ok, how do I deal with that?  

Colin Law

unread,
Mar 3, 2017, 5:21:22 PM3/3/17
to Ruby on Rails: Talk
On 3 March 2017 at 22:03, Joe Guerra <JGu...@jginfosys.com> wrote:
> Ok, how do I deal with that?

You have to recalculate the variable in each method that you need it.

Colin

Joe Guerra

unread,
Mar 3, 2017, 5:39:41 PM3/3/17
to Ruby on Rails: Talk
ok, I thought about that.  Would it be ok to like set the instant variable to a global and use that?

$remaining = @remaining

I tried that, and it seems to have worked.  I not sure if it's the best practice though.

James Jelinek

unread,
Mar 3, 2017, 6:03:11 PM3/3/17
to rubyonra...@googlegroups.com
As Colin mentioned you’d want to recalculate the variable in each method that it’s used.  Global variables may work for your use case but they are not best practice and can lead to a mutable/mutex object which may not be your intended behavior.


--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/46af96c5-857d-4742-894d-be66446bf1a0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hassan Schroeder

unread,
Mar 3, 2017, 6:06:00 PM3/3/17
to rubyonrails-talk
On Fri, Mar 3, 2017 at 2:39 PM, Joe Guerra <JGu...@jginfosys.com> wrote:
> Would it be ok to like set the instant variable
> to a global and use that?

Not if that value is going to be different for different users...

> I tried that, and it seems to have worked. I not sure if it's the best
> practice though.

It's not.

Write a separate method that creates the instance variable and use
a before_filter to set it in the methods that need it.

--
Hassan Schroeder ------------------------ hassan.s...@gmail.com
twitter: @hassan
Consulting Availability : Silicon Valley or remote

Colin Law

unread,
Mar 4, 2017, 3:18:11 AM3/4/17
to Ruby on Rails: Talk
On 3 March 2017 at 22:39, Joe Guerra <JGu...@jginfosys.com> wrote:
> ok, I thought about that. Would it be ok to like set the instant variable
> to a global and use that?
>
> $remaining = @remaining
>
> I tried that, and it seems to have worked. I not sure if it's the best
> practice though.

Definitely not. In addition to the fact that presumable @remaining is
different for different products, and a request for a different
product could come in between the two requests you are interested in
(so the global would be set for the wrong product) consider the case
where your app becomes popular enough to be distributed over multiple
instances of the server. In that case the two requests might go to
different servers so the global would not be setup for the second one.
Also consider that when using something like nginx to run your
production site that if it is not used for a while nginx may shutdown
the app and restart it when the next request comes in. Again the
global would not be set.

I suggest following Hassan's advice.

Colin


>
> On Friday, March 3, 2017 at 5:21:22 PM UTC-5, Colin Law wrote:
>>
>> On 3 March 2017 at 22:03, Joe Guerra <JGu...@jginfosys.com> wrote:
>> > Ok, how do I deal with that?
>>
>> You have to recalculate the variable in each method that you need it.
>>
>> Colin
>

Joe Guerra

unread,
Mar 4, 2017, 1:10:54 PM3/4/17
to Ruby on Rails: Talk
so basically what your saying is;

before filter: calc_remaining

def calc_renaming

         #taken query here -- I forget what I did - not at my development pc...
         @remaining = @product.qty - @taken

end 


Then call calc_renaming from the two methods I need to figure out what remaining is.

Thanks,
Joe

Colin Law

unread,
Mar 4, 2017, 3:53:46 PM3/4/17
to Ruby on Rails: Talk
On 4 March 2017 at 18:10, Joe Guerra <JGu...@jginfosys.com> wrote:
> so basically what your saying is;
>
> before filter: calc_remaining
>
> def calc_renaming
>
> #taken query here -- I forget what I did - not at my development
> pc...
> @remaining = @product.qty - @taken
>
> end
>
>
> Then call calc_renaming from the two methods I need to figure out what
> remaining is.

You won't need to call it explicitly in the methods, that is what
before_filter does. If you only need it in those two methods then
either specify that in the before filter (look at the docs for how to
do that), or don't use before filter just call it in the methods.
However if @taken is also a query on product then define a method in
product called, possibly, remaining and then in your methods just do
@remaining = @product.remaining

Colin

Joe Guerra

unread,
Mar 5, 2017, 1:23:14 PM3/5/17
to Ruby on Rails: Talk
ok, here's my method...

def calc_remaining
@taken = Cart.where('product_id' => @product).count


@remaining = @product.qty - @taken
end

but when I call it from my add to cart method, @product.qty is undefined method `qty' for nil:NilClass.

Hassan Schroeder

unread,
Mar 5, 2017, 1:37:54 PM3/5/17
to rubyonrails-talk
On Sun, Mar 5, 2017 at 10:23 AM, Joe Guerra <JGu...@jginfosys.com> wrote:

> def calc_remaining
> @taken = Cart.where('product_id' => @product).count
>
> @remaining = @product.qty - @taken
> end

> but when I call it from my add to cart method, @product.qty is undefined
> method `qty' for nil:NilClass.

And that tells you that @product is nil at that point. Where is the code
that sets that variable?

Joe Guerra

unread,
Mar 5, 2017, 1:54:04 PM3/5/17
to Ruby on Rails: Talk
It works fine in the show method,  but fails in add_to_cart.

James Jelinek

unread,
Mar 5, 2017, 1:57:39 PM3/5/17
to rubyonra...@googlegroups.com
You’re getting no method error “qty” because @product is not set in your controller action.  So you’re essentially trying to subtract @taken from something that is NIL.

You need to see @product as an instance variable in your specific controller method and this should work out for you.

-James

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.

Joe Guerra

unread,
Mar 5, 2017, 2:03:26 PM3/5/17
to Ruby on Rails: Talk
it is set up in the private section

def set_product
@product = Product.find(params[:id])
end

and I can see it in my show method... 

How do I get to see it in my 

def calc_remaining
 
@taken = Cart.where('product_id' => @product).count
 
@remaining = @product.qty - @taken
end

method?  


Colin Law

unread,
Mar 5, 2017, 3:21:00 PM3/5/17
to Ruby on Rails: Talk
On 5 March 2017 at 19:03, Joe Guerra <JGu...@jginfosys.com> wrote:
> it is set up in the private section
>
> def set_product
> @product = Product.find(params[:id])
> end
>
>
> and I can see it in my show method...
>
>
> How do I get to see it in my
>
>
> def calc_remaining
> @taken = Cart.where('product_id' => @product).count
> @remaining = @product.qty - @taken
> end
>
> method?

Presumably you know which product you are talking about in that
method, that is what it should be.

Colin
> https://groups.google.com/d/msgid/rubyonrails-talk/4cc4e498-17bc-46db-aba3-ec58db1fd918%40googlegroups.com.

Hassan Schroeder

unread,
Mar 5, 2017, 5:15:29 PM3/5/17
to rubyonrails-talk
On Sun, Mar 5, 2017 at 11:03 AM, Joe Guerra <JGu...@jginfosys.com> wrote:
> it is set up in the private section
>
> def set_product
> @product = Product.find(params[:id])
> end

That's the method *definition*, but where are you calling it for this
request?

Every request sets up its own environment.
Reply all
Reply to author
Forward
0 new messages