0

I have a controller method that passes an instance variable @show_column to a grid class. The problem is that although the value of the instance variable is available in def initialize of the grid class, it is nil outside def initialize:

The controller method:

  def index
    @show_column = (current_user && current_user.admin?)
    @grid = UsersGrid.new(params[:users_grid], @show_column) do |scope|
      scope.where(admin: false).page(params[:page]).per_page(30)
    end
    @grid.assets
  end

The grid class:

class UsersGrid
  include Datagrid
  attr_reader :show_column

  def initialize(*params, show_column)
    super *params
    @show_column = show_column
  end

  scope do
    User.order("users.created_at desc")
  end

  column(:abc, :header => "abc?", :html => true, :if => proc {@show_column == true}) do |user|
    image_tag("abc.png", title: "abc") if user.abc
  end
end

The problem is at the end with: proc {@show_column == true}. This doesn't work because @show_column is always nil. I've used a debugger to try to find some additional information. I shows that @show_column is set correctly in the controller; its value is true as it should be given the user I logged in with. Also, inside def initialize its value is true. However, outside def initialize in the grid class, its value is nil. Any ideas how to solve this?

6
  • Change :if => proc {@show_column == true}) line in your UsersGrid class to this: :if => proc {show_column == true}) and then try Commented May 28, 2015 at 9:57
  • Then it produces the error undefined local variable or method 'show_column' for UsersGrid:Class. Commented May 28, 2015 at 10:01
  • Try attr_accessor instead of attr_reader Commented May 28, 2015 at 10:03
  • @TriveniBadgujar you really think adding a setter could change the outcome? Commented May 28, 2015 at 10:04
  • Now we see a progress here, don't we? It seems @show_column is expected to be a class variable not instance variable. Could you explain from where you're writing such a code? UsersGrid class looks like a Ruby class with no active record... is it coming from Datagrid module? Commented May 28, 2015 at 10:05

2 Answers 2

1

According to the documentation, replace:

:if => proc {@show_column == true})

with:

:if => proc { |grid| grid.show_column == true})

or:

:if => :show_column
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, :if => proc { |grid| grid.show_column == true} worked!
0

Inside a class declaration, self is the class itself, not an instance of the class. So, @show_column is an instance variable of UsersGrid, not an instance variable of an instance of UsersGrid.

4 Comments

While this answers the implicit question (why is it like this), it doesn't deal with the explicit one (how do I overcome this). OP could use something more than a hint, I think. :)
well it was in a proc, and unless you look at the code you cant be sure of its binding.
@apneadiving: You mean it could be instance_eval'd? True, but the error message the OP posted in the comments clearly talks about UsersGrid's singleton class, so it's clear that self is UsersGrid.
true, but I guess you know you wrote a nice comment though not an answer :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.