request.format = :mobile causes error "undefined method `ref' for nil:NilClass"

I'm just trying to set the request format by detecting a mobile user agent.

This used to work in Rails 2:

request.format = :mobile

Just trying to make it render with a "mobile" format

home.mobile.html.haml

For some reason this causes "undefined method `ref' for nil:NilClass" somewhere deep inside activesupport --- is this no longer the way to do this in Rails 3? (I'm on 3.0.5)

Thanks,
Jason

This does indeed still work, though you should use home.mobile.haml. If that doesn’t work, I’d suggest posting a full stack trace and code to a more appropriate list (http://groups.google.com/group/rubyonrails-talk) since this one is for core issues.

Regards,
Ben Langfeld

Thanks – didn’t seem to work. I can reproduce this easily on a fresh Rails 3.0.7 app with no gems installed, and the error is buried deep inside of ActiveScaffold so I thought this was the right list. However, I will follow-up with a complete stacktrace and also code on the general list, thanks.

-Jason

I posted this to the Rails Talk list but no one responded. I'm not
exactly sure what "rails core" is defined as -- this problem is deep
inside activesupport, can be reproduced in seconds on a fresh new
Rails app, and I think setting the format request seems pretty "core"
to the platform to me, so I'm still not sure if this is the right list
but it seem like this is in fact a Rails core problem.

I'm gonna re-post here to see if anyone has an answer. At a very
minimum, can someone try to reproduce these steps (it's very easy) and
just tell me if they get the same bug. Thanks. Seems like the feature
should work out of the box but I'm getting this totally mysterious bug
that doesn't show a stack trace to any line of code inside my app.

I have a strange problem with setting request.format = :mobile

I can reproduce this problem on a completely fresh Rails 3.0.7 app
with no special gems. This seemed to work well in Rails 2 but for some
reason is hiccuping here, not sure what's different in Rails 3 that
makes this hiccup. If you look at the stack track, it doesn't even
pass through my app stack once -- weird -- maybe this is a problem
with Passenger? Anyone see anything i'm doing wrong here? Your tips
are much appreciated, this is baffling me.

Step-by-step instructions to reproduce:

Totally fresh rails app (rails new test_mobile), then go delete
public/
index.html

routes.rb __________________________________

TestMobile::Application.routes.draw do
root :to => "application#welcome"
end

application_controller.rb __________________________

class ApplicationController < ActionController::Base
protect_from_forgery

def welcome
   render "welcome/index"
end

before_filter :check_mobile

def check_mobile
   request.format = :mobile if request.env["HTTP_USER_AGENT"] =~ /
iPhone/
end
end

views/welcome/index.html.erb ______________________________________

this is my regular site

views/welcome/index.mobile.erb ____________________________________

this is my mobile site

That's it -- those are all the steps one needs to take to reproduce
this, no gem configuration necessary.

Set it up with Passenger (as test-mobile.local), go to Safrai, load
test-mobile.local, you get "this is my regular site". Then switch
Develop > User Agent to "Safari iOS 4.1", reload the page, and bam:

NoMethodError in ApplicationsController#welcome

undefined method `ref' for nil:NilClass
Rails.root: /Users/jason/Projects/DEVELOPMENT/ROR/test_mobile

Application Trace | Framework Trace | Full Trace
activesupport (3.0.7) lib/active_support/whiny_nil.rb:48:in
`method_missing'
actionpack (3.0.7) lib/action_controller/metal/rendering.rb:10:in
`process_action'
actionpack (3.0.7) lib/action_controller/metal/rendering.rb:10:in
`map'
actionpack (3.0.7) lib/action_controller/metal/rendering.rb:10:in
`process_action'
actionpack (3.0.7) lib/abstract_controller/callbacks.rb:18:in
`process_action'
activesupport (3.0.7) lib/active_support/callbacks.rb:441:in
`_run__2115867319__process_action__733682996__callbacks'
activesupport (3.0.7) lib/active_support/callbacks.rb:410:in `send'
activesupport (3.0.7) lib/active_support/callbacks.rb:410:in
`_run_process_action_callbacks'
activesupport (3.0.7) lib/active_support/callbacks.rb:94:in `send'
activesupport (3.0.7) lib/active_support/callbacks.rb:94:in
`run_callbacks'
actionpack (3.0.7) lib/abstract_controller/callbacks.rb:17:in
`process_action'
actionpack (3.0.7) lib/action_controller/metal/instrumentation.rb:
30:in `process_action'
activesupport (3.0.7) lib/active_support/notifications.rb:52:in
`instrument'
activesupport (3.0.7) lib/active_support/notifications/instrumenter.rb:
21:in `instrument'
activesupport (3.0.7) lib/active_support/notifications.rb:52:in
`instrument'
actionpack (3.0.7) lib/action_controller/metal/instrumentation.rb:
29:in `process_action'
actionpack (3.0.7) lib/action_controller/metal/rescue.rb:17:in
`process_action'
actionpack (3.0.7) lib/abstract_controller/base.rb:119:in `process'
actionpack (3.0.7) lib/abstract_controller/rendering.rb:41:in
`process'
actionpack (3.0.7) lib/action_controller/metal.rb:138:in `dispatch'
actionpack (3.0.7) lib/action_controller/metal/rack_delegation.rb:
14:in `dispatch'
actionpack (3.0.7) lib/action_controller/metal.rb:178
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:62:in
`call'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:62:in
`dispatch'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:27:in
`call'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:148:in `call'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:93:in
`recognize'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:68:in
`optimized_each'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:92:in
`recognize'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:139:in `call'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:493:in
`call'
actionpack (3.0.7) lib/action_dispatch/middleware/
best_standards_support.rb:17:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/head.rb:14:in `call'
rack (1.2.2) lib/rack/methodoverride.rb:24:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/params_parser.rb:
21:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/flash.rb:182:in
`call'
actionpack (3.0.7) lib/action_dispatch/middleware/session/
abstract_store.rb:149:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/cookies.rb:302:in
`call'
activerecord (3.0.7) lib/active_record/query_cache.rb:32:in `call'
activerecord (3.0.7) lib/active_record/connection_adapters/abstract/
query_cache.rb:28:in `cache'
activerecord (3.0.7) lib/active_record/query_cache.rb:12:in `cache'
activerecord (3.0.7) lib/active_record/query_cache.rb:31:in `call'
activerecord (3.0.7) lib/active_record/connection_adapters/abstract/
connection_pool.rb:354:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/callbacks.rb:46:in
`call'
activesupport (3.0.7) lib/active_support/callbacks.rb:416:in
`_run_call_callbacks'
actionpack (3.0.7) lib/action_dispatch/middleware/callbacks.rb:44:in
`call'
rack (1.2.2) lib/rack/sendfile.rb:107:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/remote_ip.rb:48:in
`call'
actionpack (3.0.7) lib/action_dispatch/middleware/show_exceptions.rb:
47:in `call'
railties (3.0.7) lib/rails/rack/logger.rb:13:in `call'
rack (1.2.2) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.7) lib/active_support/cache/strategy/local_cache.rb:
72:in `call'
rack (1.2.2) lib/rack/lock.rb:11:in `call'
rack (1.2.2) lib/rack/lock.rb:11:in `synchronize'
rack (1.2.2) lib/rack/lock.rb:11:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/static.rb:30:in
`call'
railties (3.0.7) lib/rails/application.rb:168:in `call'
railties (3.0.7) lib/rails/application.rb:77:in `send'
railties (3.0.7) lib/rails/application.rb:77:in `method_missing'
passenger (3.0.7) lib/phusion_passenger/rack/request_handler.rb:96:in
`process_request'
passenger (3.0.7) lib/phusion_passenger/abstract_request_handler.rb:
513:in `accept_and_process_next_request'
passenger (3.0.7) lib/phusion_passenger/abstract_request_handler.rb:
274:in `main_loop'
passenger (3.0.7) lib/phusion_passenger/rack/application_spawner.rb:
205:in `start_request_handler'
passenger (3.0.7) lib/phusion_passenger/rack/application_spawner.rb:
170:in `send'
passenger (3.0.7) lib/phusion_passenger/rack/application_spawner.rb:
170:in `handle_spawn_application'
passenger (3.0.7) lib/phusion_passenger/utils.rb:479:in `safe_fork'
passenger (3.0.7) lib/phusion_passenger/rack/application_spawner.rb:
165:in `handle_spawn_application'
passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:357:in
`__send__'
passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:357:in
`server_main_loop'
passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:206:in
`start_synchronously'
passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:180:in
`start'
passenger (3.0.7) lib/phusion_passenger/rack/application_spawner.rb:
128:in `start'
passenger (3.0.7) lib/phusion_passenger/spawn_manager.rb:253:in
`spawn_rack_application'
passenger (3.0.7) lib/phusion_passenger/abstract_server_collection.rb:
132:in `lookup_or_add'
passenger (3.0.7) lib/phusion_passenger/spawn_manager.rb:246:in
`spawn_rack_application'
passenger (3.0.7) lib/phusion_passenger/abstract_server_collection.rb:
82:in `synchronize'
passenger (3.0.7) lib/phusion_passenger/abstract_server_collection.rb:
79:in `synchronize'
passenger (3.0.7) lib/phusion_passenger/spawn_manager.rb:244:in
`spawn_rack_application'
passenger (3.0.7) lib/phusion_passenger/spawn_manager.rb:137:in
`spawn_application'
passenger (3.0.7) lib/phusion_passenger/spawn_manager.rb:275:in
`handle_spawn_application'
passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:357:in
`__send__'
passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:357:in
`server_main_loop'
passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:206:in
`start_synchronously'
passenger (3.0.7) helper-scripts/passenger-spawn-server:99

Request

Parameters:

{"format"=>"mobile"}
Show session dump

Show env dump

Response

Headers:

None

I posted this to the Rails Talk list but no one responded. I'm not
exactly sure what "rails core" is defined as -- this problem is deep
inside activesupport, can be reproduced in seconds on a fresh new
Rails app, and I think setting the format request seems pretty "core"
to the platform to me, so I'm still not sure if this is the right list
but it seem like this is in fact a Rails core problem.

The error message you're receiving is pretty confusing, so there's
definitely something nicer we should do there. However I'm guessing
that this isn't a bug.

You have to register a mime type for that extension, or an alias, if
you want it to work. Something like:

Mime::Type.register_alias "text/html", :mobile

If you don't, then rails can't tell what mime type to send with the response.

This is indeed the issue and the proper solution. Or you could use mobile_fu instead: https://rubygems.org/gems/mobile-fu

Regards,
Ben Langfeld

Ahh, yes, confirmed -- this works!

Thanks so much. I didn't realize this was a necessary step.

-Jason

Yes, confirmed--- that was the problem, I didn't (/realize I had to) set the MIME type for mobile in config/initializers/mime_types.rb

if the error message could say something like "You need to register the mime type to use for format for :mobile in config/initializers/mime_types.rb" that would be much more helpful. It makes perfect sense, I just didn't realize I had to do that.

Thanks

Yes, I think we're trying to call #ref without checking for its presence first. I'll patch that.

:slight_smile: