# show method variable

**URL:** <https://discuss.rubyonrails.org/t/show-method-variable/72409>\
**Category:** rubyonrails-talk\
**Created:** [March 2, 2017, 4:07pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409 "2017-03-02T16:07:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 2, 2017, 4:07pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/1 "2017-03-02T16:07:06Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Tamara\_Temple](https://avatars.discourse-cdn.com/v4/letter/t/c37758/32.png) [@Tamara\_Temple](https://discuss.rubyonrails.org/u/Tamara_Temple)\
**Post date:** [March 2, 2017, 4:14pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/2 "2017-03-02T16:14:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 2, 2017, 4:29pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/3 "2017-03-02T16:29:44Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 3, 2017, 5:34pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/4 "2017-03-03T17:34:01Z")

</div>

ok, I added this piece of code…

```ruby
  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)
```

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 3, 2017, 5:51pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/5 "2017-03-03T17:51:29Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Colin\_Law](https://avatars.discourse-cdn.com/v4/letter/c/b9e5f3/32.png) [@Colin\_Law](https://discuss.rubyonrails.org/u/Colin_Law)\
**Post date:** [March 3, 2017, 6:20pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/6 "2017-03-03T18:20:07Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 3, 2017, 10:03pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/7 "2017-03-03T22:03:55Z")

</div>

Ok, how do I deal with that?

---

<div class="post-metadata">

**Author:** ![Colin\_Law](https://avatars.discourse-cdn.com/v4/letter/c/b9e5f3/32.png) [@Colin\_Law](https://discuss.rubyonrails.org/u/Colin_Law)\
**Post date:** [March 3, 2017, 10:20pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/8 "2017-03-03T22:20:37Z")

</div>

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

Colin

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 3, 2017, 10:39pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/9 "2017-03-03T22:39:41Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![James\_Jelinek](https://avatars.discourse-cdn.com/v4/letter/j/e19b73/32.png) [@James\_Jelinek](https://discuss.rubyonrails.org/u/James_Jelinek)\
**Post date:** [March 3, 2017, 11:02pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/10 "2017-03-03T23:02:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![hassan](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/hassan/32/714_2.png) [@hassan](https://discuss.rubyonrails.org/u/hassan)\
**Post date:** [March 3, 2017, 11:05pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/11 "2017-03-03T23:05:25Z")

</div>

> 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.

---

<div class="post-metadata">

**Author:** ![Colin\_Law](https://avatars.discourse-cdn.com/v4/letter/c/b9e5f3/32.png) [@Colin\_Law](https://discuss.rubyonrails.org/u/Colin_Law)\
**Post date:** [March 4, 2017, 8:17am UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/12 "2017-03-04T08:17:21Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 4, 2017, 6:10pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/13 "2017-03-04T18:10:54Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Colin\_Law](https://avatars.discourse-cdn.com/v4/letter/c/b9e5f3/32.png) [@Colin\_Law](https://discuss.rubyonrails.org/u/Colin_Law)\
**Post date:** [March 4, 2017, 8:52pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/14 "2017-03-04T20:52:40Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 5, 2017, 6:23pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/15 "2017-03-05T18:23:13Z")

</div>

ok, here’s my method…

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

  @remaining = @product.qty - @taken
end

```

```ruby

```

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

```

---

<div class="post-metadata">

**Author:** ![hassan](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/hassan/32/714_2.png) [@hassan](https://discuss.rubyonrails.org/u/hassan)\
**Post date:** [March 5, 2017, 6:37pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/16 "2017-03-05T18:37:40Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 5, 2017, 6:54pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/17 "2017-03-05T18:54:03Z")

</div>

It works fine in the show method, but fails in add\_to\_cart.

---

<div class="post-metadata">

**Author:** ![James\_Jelinek](https://avatars.discourse-cdn.com/v4/letter/j/e19b73/32.png) [@James\_Jelinek](https://discuss.rubyonrails.org/u/James_Jelinek)\
**Post date:** [March 5, 2017, 6:56pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/18 "2017-03-05T18:56:55Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joe\_Guerra](https://avatars.discourse-cdn.com/v4/letter/j/c89c15/32.png) [@Joe\_Guerra](https://discuss.rubyonrails.org/u/Joe_Guerra)\
**Post date:** [March 5, 2017, 7:03pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/19 "2017-03-05T19:03:25Z")

</div>

it is set up in the private section

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

```

```ruby

```

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

```

```ruby

```

```ruby
**How do I get to see it in my**

```

```ruby

```

```ruby

```

def calc\_remaining @taken = Cart.where(‘product\_id’ =\> @product).count @remaining = @product.qty - @taken end

```ruby
method?

```

```ruby

```

```ruby

```

---

<div class="post-metadata">

**Author:** ![Colin\_Law](https://avatars.discourse-cdn.com/v4/letter/c/b9e5f3/32.png) [@Colin\_Law](https://discuss.rubyonrails.org/u/Colin_Law)\
**Post date:** [March 5, 2017, 8:20pm UTC](https://discuss.rubyonrails.org/t/show-method-variable/72409/20 "2017-03-05T20:20:18Z")

</div>

> it is set up in the private section
> 
> def set\_product &nbsp;&nbsp;@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

[Next page](https://discuss.rubyonrails.org/t/show-method-variable/72409.md?page=2)
