Topic: Strange problem trying to access variables from a view.

Ok, I am having a completely illogical problem here.

I have a @campaigns variable declared within the display action of one of my controllers. Strangely enough, when I try to access the variable out of the view, it gives me an error.

Here is the code for the display action in the controller:

app/controllers/controlpanels_controller.rb

def display
  @campaigns = Campaign.find(:all,   :conditions => [ "user_id = ?", current_user.id])
end

Simple enough right?

Here is the code where I try to call this variable in the view at app/views/controllers/controlpanels/display.rhtml

<table>
<% @campaigns.each do |campaign| %>
  <tr>
    <td><%= campaign.name %></td>
    <td><%= link_to 'Show', :action => 'show', :id => campaign %></td>
    <td><%= link_to 'Edit', :action => 'edit', :id => campaign %></td>
    <td><%= link_to 'Destroy', { :action => 'destroy', :id => campaign }, :confirm => 'Are you sure?', :post => true %></td>
  </tr>
<% end %>
</table>

seems straightforward - the variable is declared in the controller, used in the view, such as is done hundreds or thousands of times in every Ruby program. Same as is done in all my other controllers and views. So how come this time I get this error?

 NoMethodError in Controlpanels#index

Showing app/views/controlpanels/display.rhtml where line #1 raised:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each

Extracted source (around line #1):

1: <% for campaign in @campaigns %>
2: <table>
3:   <tr>
4:     <td><%= campaign.name %></td>

RAILS_ROOT: script/../config/..
Application Trace | Framework Trace | Full Trace

#{RAILS_ROOT}/app/views/controlpanels/display.rhtml:1:in `_run_rhtml_47app47views47controlpanels47display46rhtml'
app/controllers/controlpanels_controller.rb:6:in `index'
-e:4

vendor/rails/actionpack/lib/action_view/base.rb:328:in `compile_and_render_template'
vendor/rails/actionpack/lib/action_view/base.rb:303:in `render_template'
vendor/rails/actionpack/lib/action_view/base.rb:263:in `render_file'
vendor/rails/actionpack/lib/action_controller/base.rb:803:in `render_file'
vendor/rails/actionpack/lib/action_controller/base.rb:735:in `render_with_no_layout'
vendor/rails/actionpack/lib/action_controller/base.rb:860:in `render_without_layout'
vendor/rails/actionpack/lib/action_controller/base.rb:795:in `render_action'
vendor/rails/actionpack/lib/action_controller/base.rb:745:in `render_with_no_layout'
vendor/rails/activesupport/lib/active_support/deprecation.rb:43:in `silence'
vendor/rails/actionpack/lib/action_controller/base.rb:744:in `render_with_no_layout'
vendor/rails/actionpack/lib/action_controller/layout.rb:244:in `render_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
vendor/rails/actionpack/lib/action_controller/base.rb:1092:in `perform_action_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:632:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:619:in `perform_action_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
vendor/rails/actionpack/lib/action_controller/rescue.rb:112:in `perform_action'
vendor/rails/actionpack/lib/action_controller/base.rb:427:in `process_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:624:in `process_without_session_management_support'
vendor/rails/actionpack/lib/action_controller/session_management.rb:114:in `process'
vendor/rails/actionpack/lib/action_controller/base.rb:330:in `process'
vendor/rails/railties/lib/dispatcher.rb:41:in `dispatch'
vendor/rails/railties/lib/webrick_server.rb:110:in `handle_dispatch'
vendor/rails/railties/lib/webrick_server.rb:76:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
vendor/rails/railties/lib/webrick_server.rb:63:in `dispatch'
vendor/rails/railties/lib/commands/servers/webrick.rb:59
/usr/lib/ruby/1.8/rubygems/custom_require.rb:21:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:490:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:337:in `new_constants_in'
vendor/rails/activesupport/lib/active_support/dependencies.rb:490:in `require'
vendor/rails/railties/lib/commands/server.rb:39
script/server:3

#{RAILS_ROOT}/app/views/controlpanels/display.rhtml:1:in `_run_rhtml_47app47views47controlpanels47display46rhtml'
vendor/rails/actionpack/lib/action_view/base.rb:328:in `compile_and_render_template'
vendor/rails/actionpack/lib/action_view/base.rb:303:in `render_template'
vendor/rails/actionpack/lib/action_view/base.rb:263:in `render_file'
vendor/rails/actionpack/lib/action_controller/base.rb:803:in `render_file'
vendor/rails/actionpack/lib/action_controller/base.rb:735:in `render_with_no_layout'
vendor/rails/actionpack/lib/action_controller/base.rb:860:in `render_without_layout'
vendor/rails/actionpack/lib/action_controller/base.rb:795:in `render_action'
vendor/rails/actionpack/lib/action_controller/base.rb:745:in `render_with_no_layout'
vendor/rails/activesupport/lib/active_support/deprecation.rb:43:in `silence'
vendor/rails/actionpack/lib/action_controller/base.rb:744:in `render_with_no_layout'
vendor/rails/actionpack/lib/action_controller/layout.rb:244:in `render_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
app/controllers/controlpanels_controller.rb:6:in `index'
vendor/rails/actionpack/lib/action_controller/base.rb:1092:in `perform_action_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:632:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
vendor/rails/actionpack/lib/action_controller/filters.rb:619:in `perform_action_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
vendor/rails/actionpack/lib/action_controller/rescue.rb:112:in `perform_action'
vendor/rails/actionpack/lib/action_controller/base.rb:427:in `process_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:624:in `process_without_session_management_support'
vendor/rails/actionpack/lib/action_controller/session_management.rb:114:in `process'
vendor/rails/actionpack/lib/action_controller/base.rb:330:in `process'
vendor/rails/railties/lib/dispatcher.rb:41:in `dispatch'
vendor/rails/railties/lib/webrick_server.rb:110:in `handle_dispatch'
vendor/rails/railties/lib/webrick_server.rb:76:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
vendor/rails/railties/lib/webrick_server.rb:63:in `dispatch'
vendor/rails/railties/lib/commands/servers/webrick.rb:59
/usr/lib/ruby/1.8/rubygems/custom_require.rb:21:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:490:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:337:in `new_constants_in'
vendor/rails/activesupport/lib/active_support/dependencies.rb:490:in `require'
vendor/rails/railties/lib/commands/server.rb:39
script/server:3
-e:4

Request

Parameters:

None

Show session dump

---
:user: 1
:return_to:
flash: !map:ActionController::Flash::FlashHash {}


Response

Headers:

{"cookie"=>[],
"Cache-Control"=>"no-cache"}


I've tried a simple case where the view contains nothing but a debug call to display @campaigns; that returns nil. So, for some reason, the variable can not be seen in the view. If I remove the variable reference from the view, it seems to render. Does anyone have any idea why this would be?

I am completely stuck. Thank you in advance for any help or suggestions!

Check out my Blog.

Re: Strange problem trying to access variables from a view.

But I think there is more going on than you are telling. You are using display.rhtml but the error is raised in the controller's index action.

Also the code snippet you provided is using each to do looping, while the error message shows you are using for to do looping.

Are you actually calling the index action and redirecting to display? or rendering display? I have a feeling the involvement of the two actions is why you are getting a null pointer.

Re: Strange problem trying to access variables from a view.

tortoise wrote:

But I think there is more going on than you are telling. You are using display.rhtml but the error is raised in the controller's index action.

index is nothing but a redirect to display. display accessed directly gives the exact same error

Also the code snippet you provided is using each to do looping, while the error message shows you are using for to do looping.

between copying the various messages, I changed the code a touch to see if the code was at fault. I forgot to correlate the two versions prior to posting the information here.

Are you actually calling the index action and redirecting to display? or rendering display? I have a feeling the involvement of the two actions is why you are getting a null pointer.

See the first response tongue

Check out my Blog.

Re: Strange problem trying to access variables from a view.

Ok, I have simplified matters greatly.

here is my controller code: (app/controllers/controlpanels_controller.rb)

class ControlpanelsController < ApplicationController

before_filter :login_required

def index
  render :action => 'display'
end

def display
  @campaigns = current_user.campaigns(true)
  @foo = "foobury"
end

def test
  @campaigns = current_user.campaigns(true)
  @foo = "foobury"
end

end


Here is the view code for app/views/controlpanels/display.rhtml:

<%= @campaigns.inspect %><br/>
<%= @current_user.inspect %><br/>
<%= @foo.inspect %>

Here is the view code for app/views/controlpanels/test.rhtml:

<%= @foo.inspect %>
<br/><%= @current_user.inspect %>
<br/><%= @campaigns.inspect %>

now the output for http://localhost:3000/controlpanels/display is:

nil
#"7e3041ebc2fc05a40c60028e2c4901a81035d3cd", "activated_at"=>"2006-12-13 22:30:03", "updated_at"=>nil, "crypted_password"=>"00742970dc9e6319f8019fd54864d3ea740f04b1", "activation_code"=>"8f24789ae988411ccf33ab0c30fe9106fab32e9b", "remember_token_expires_at"=>nil, "id"=>"1", "remember_token"=>nil, "login"=>"quentin", "created_at"=>"2006-12-13 22:30:03", "email"=>"quentin@example.com"}>
nil

http://localhost:3000/controlpanels/test:

"foobury"
#"7e3041ebc2fc05a40c60028e2c4901a81035d3cd", "activated_at"=>"2006-12-13 22:30:03", "updated_at"=>nil, "crypted_password"=>"00742970dc9e6319f8019fd54864d3ea740f04b1", "activation_code"=>"8f24789ae988411ccf33ab0c30fe9106fab32e9b", "remember_token_expires_at"=>nil, "id"=>"1", "remember_token"=>nil, "login"=>"quentin", "created_at"=>"2006-12-13 22:30:03", "email"=>"quentin@example.com"}, @campaigns=[#"Caydel's test", "id"=>"1", "user_id"=>"1"}>]>
[#"Caydel's test", "id"=>"1", "user_id"=>"1"}>]

As you can see, the controller code in both test and display actions is identical, as is the view code. Yet one is resolving to the variables, one is resolving to nil.

This is seriously screwed up. There is no reason that I can think of for this behaviour. BTW, this is Edge Rails. A helpful user in the #rubyonrails Freenode IRC told me to change the line of controller code in the first post to read @campaigns = current_user.campaigns(true), in order to force the associations to load.

Does that make more sense?

Last edited by Caydel (2006-12-19 01:35:45)

Check out my Blog.

Re: Strange problem trying to access variables from a view.

render :action => 'foo'

will literally just render foo.rhtml using the current state of the system. redirect_to will call the action in question as if it had been the original action called.

Change

render :action => 'display'

to

redirect_to :action => 'display'

Re: Strange problem trying to access variables from a view.

Thanks for that - I changed it to redirect_to. Regardless, the issue occured still when I accessed display directly, and now that the call has been changed, I am still seeing this issue.

Brian

Check out my Blog.

Re: Strange problem trying to access variables from a view.

Just to add a little more information, I've installed the debug-view-helper plugin from http://www.agilewebdevelopment.com/plug … ew_helper, and have taken a look at the pages.

It seems that the problem lies in between the controllers and the views; while everything looks ok for the test action and view, the @campaigns and @foo variables are not sent to the display method.

Thanks for the suggestions so far, tortoise. I am really hoping to get this fixed, since this app is dead in the water until I can figure this out. I've already spent about 10 hours now trying to figure out why this is happening.

display debug info:

Rails Debug Console
Request Parameters:
action    "display"
controller    "controlpanels"
Session Variables:
user   

--- 1

return_to   

---

Flash Variables:
Assigned Template Variables:
_session   

--- !ruby/object:CGI::Session
data: &id001
  :user: 1
  flash: !map:ActionController::Flash::FlashHash {}

  :return_to:
dbman: &id002 !ruby/object:CGI::Session::PStore
  hash: *id001
  p: !ruby/object:PStore
    abort: false
    filename: script/../config/../tmp/sessions//ruby_sess.3b0adb54b82ed35d
    rdonly: false
    table:
    transaction: false
dbprot:
- *id002
new_session: false
session_id: 6e2e7ab2efe82f5cadc29027516554fc

action_name   

--- display

request_origin   

--- 127.0.0.1 at 2006-12-19 06:36:46

(snipped request and response headers because post was over 64k maximum)

_cookies   

---
_session_id:
- 6e2e7ab2efe82f5cadc29027516554fc

current_user   

--- !ruby/object:User
attributes:
  salt: 3fcd60b05b0834a76229c6a2cbd3ee9b7641ca25
  activated_at:
  updated_at: 2006-12-19 00:08:18
  crypted_password: 95d7f72df465c7108b7cfdbb24966cf0dd151912
  activation_code: e27763c5ce63a28aa25368d7ca8c4a89e64a68b6
  remember_token_expires_at:
  id: "1"
  remember_token:
  login: caydel
  created_at: 2006-12-19 00:08:18
  email: brian@caydel.com

_flash   

--- !map:ActionController::Flash::FlashHash {}

_headers   

---
Status: 200 OK
cookie: []

Cache-Control: no-cache

_params   

--- !map:HashWithIndifferentAccess
action: display
controller: controlpanels


test view:
Rails Debug Console
Request Parameters:
action    "test"
controller    "controlpanels"
Session Variables:
user   

--- 1

return_to   

---

Flash Variables:
Assigned Template Variables:
_session   

--- !ruby/object:CGI::Session
data: &id001
  :user: 1
  flash: !map:ActionController::Flash::FlashHash {}

  :return_to:
dbman: &id002 !ruby/object:CGI::Session::PStore
  hash: *id001
  p: !ruby/object:PStore
    abort: false
    filename: script/../config/../tmp/sessions//ruby_sess.3b0adb54b82ed35d
    rdonly: false
    table:
    transaction: false
dbprot:
- *id002
new_session: false
session_id: 6e2e7ab2efe82f5cadc29027516554fc

action_name   

--- test

request_origin   

--- 127.0.0.1 at 2006-12-19 06:38:31

(snipped request and response headers because post was over 64k maximum)

foo1   

---
- !ruby/object:Campaign
  attributes:
    name: Caydel's test
    id: "1"
    user_id: "1"
- !ruby/object:Campaign
  attributes:
    name: Caydel's 2
    id: "2"
    user_id: "1"
- !ruby/object:Campaign
  attributes:
    name: Caydel's 3
    id: "3"
    user_id: "1"

_cookies   

---
_session_id:
- 6e2e7ab2efe82f5cadc29027516554fc

foo   

--- foobury

current_user   

--- !ruby/object:User
attributes:
  salt: 3fcd60b05b0834a76229c6a2cbd3ee9b7641ca25
  activated_at:
  updated_at: 2006-12-19 00:08:18
  crypted_password: 95d7f72df465c7108b7cfdbb24966cf0dd151912
  activation_code: e27763c5ce63a28aa25368d7ca8c4a89e64a68b6
  remember_token_expires_at:
  id: "1"
  remember_token:
  login: caydel
  created_at: 2006-12-19 00:08:18
  email: brian@caydel.com
campaigns:
- !ruby/object:Campaign
  attributes:
    name: Caydel's test
    id: "1"
    user_id: "1"
- !ruby/object:Campaign
  attributes:
    name: Caydel's 2
    id: "2"
    user_id: "1"
- !ruby/object:Campaign
  attributes:
    name: Caydel's 3
    id: "3"
    user_id: "1"

_flash   

--- !map:ActionController::Flash::FlashHash {}

_headers   

---
Status: 200 OK
cookie: []

Cache-Control: no-cache

_params   

--- !map:HashWithIndifferentAccess
action: test
controller: controlpanels

Last edited by Caydel (2006-12-19 07:57:48)

Check out my Blog.

Re: Strange problem trying to access variables from a view.

Display is a ruby method built into Object, and it looks like you are overriding it in your controller. Try renaming it to something else and see if it works. That would explain why only one of two identical actions and views is working.

updated

I've tried renaming one of my own controller actions to display and it works fine so I suppose that can't be it. I would try renaming test to display, and rename display to test, in both the actions and the views and see which one works then.

Last edited by dahuk (2006-12-19 09:51:32)