Forum: Ruby on Rails Controllers in folders and helper scope in Rails >1.0

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
RafaÅ? Komorowski (Guest)
on 2006-04-23 22:53
(Received via mailing list)
Hi,

Here's my problem. I tried to google it, read the release-docs and
haven't found anything similar.
My application uses folders to store controllers, as described in the
Rails book. I need to have same-named controllers for admin and for
users, so it looks like this:

/app/controllers/admin/project_controller.rb
/app/controllers/admin/...
/app/controllers/project_controller.rb
/app/controllers/...

The controller-classes are properly scoped like this:

	/app/controllers/admin/project_controller.rb has:

		class Admin::ProjectController < ApplicationController
		  layout  "admin"
		  def index
			...
		  end

	/app/controllers/project_controller.rb has:

		class ProjectController < ApplicationController
		  layout  "user"
		  def index
			...
		  end

Those controllers make use of helpers, and again, there are global
ones (used by both by users and admins), and special ones for admins.
So it looks like this:

/app/helpers/admin/project_helper.rb
/app/helpers/admin/...
/app/helpers/project_helper.rb
/app/helpers/...


The admin helper contains properly scoped content:

	module Admin::ProjectHelper
	...
	end

and normal helper has also:

	module ProjectHelper
	...
	end


It is important, that admin-scope controllers are also accessing and
using constants and classes defined in user-scope helpers. This
worked fine in 0.14.x and in 1.0 versions of Rails. Now I'm trying to
move to 1.1.1 through Locomotive bundle or 1.1.2 through normal means
(sudo gem update rails, ..., etc) and this behavour breaks.

The original working code in the admin-controller is like this:

	class Admin::ProjectController < ApplicationController
	  layout  "admin"
	  def index
	    @project_display_options =
ProjectHelper::ProjectDisplayOptions.new(params, session)
	    ...

and it accessed ProjectDisplayOptions class from the user-scope helper:

	module ProjectHelper
	  class ProjectDisplayOptions
	    attr_accessor :project
	    ...


Now, in Rails 1.1.x, my application breaks as if the user-helper
scope was unavailable for admin-scope controller:

	NameError in Admin/projectController#index
	uninitialized constant ProjectDisplayOptions
	...
	#{RAILS_ROOT}/app/controllers/admin/project_controller.rb:6:in `index'

line 6 leads to:
	@project_display_options = ProjectHelper::ProjectDisplayOptions.new
(params, session)

The browser response also contains this:
	This error occured while loading the following files:
	   admin/project_helper/project_display_options.rb

which seems to come from the new dynamic mechanism trying to load an
unknown class from a same-named file. But I'm not sure is this is
really what's supposed to happen.
I can fix the problem by copying-pasting the problematic class from
user-scope helper to the admin-scope-helper, but this is not DRY, of
course. And what happened, that the behaviour of Rails has changes in
1.1? I can't find anything relevant in the release-notes.
My application is a small internal tool, but certainly is was running
for the last six months on 0.13, 0.14 and on 1.0 versions of Rails.

Any help? TIA.

--

RafaÅ? Komorowski
removed_email_address@domain.invalid
GG: 4083718
<http://homepage.mac.com/komor/iblog/>
RafaÅ? Komorowski (Guest)
on 2006-04-25 01:43
(Received via mailing list)
On 23/04/2006, at 20:49, RafaÅ? Komorowski wrote:

> My application uses folders to store controllers, as described in
> the Rails book.
[cut]
> /app/controllers/admin/project_controller.rb
> /app/controllers/admin/...
> /app/controllers/project_controller.rb
> /app/controllers/...
[cut]
> /app/helpers/admin/project_helper.rb
> /app/helpers/admin/...
> /app/helpers/project_helper.rb
> /app/helpers/...

[cut]
> Now, in Rails 1.1.x, my application breaks as if the user-helper
> scope was unavailable for admin-scope controller:


I solved my problem by changing this:

     @project_display_options =
ProjectHelper::ProjectDisplayOptions.new(params, session)

to this:

     @project_display_options
= ::ProjectHelper::ProjectDisplayOptions.new(params, session)

in the admin controller code.

Seems reasonable, but still I'm pretty sure something has changed in
the Rails 1.1, because I've done a test:
- make a fresh empty app,
- generate controllers (with admin in subfolder),
- fill-in a placeholder code in controllers, helpers and views.
- see if it works to access user-scope helper in admin-scope controller.

The interesting thing happens then in Rails 1.1.x: if my initial
request is the admin-scope one (http://localhost:3000/admin/project)
then application fails, as if Rails couldn't see the user-scope
helper yet. But after issuing user-scope request (http://localhost:
3000/project) the admin controller runs okay, as if Rails already
"saw" the helper and loaded it properly. I'm wondering if this is the
way Rails works?

All those tests were done in Rails 1.1.2 installed by normal means
(http://hivelogic.com/articles/2005/12/01/
ruby_rails_lighttpd_mysql_tiger) on Mac OS X 10.4.6, and also through
Locomotive with 1.1.1 bundle, and they fail in the described way.
But when using Locomotive with 1.0 bundle the app succeeds always,
that is: admin-scope controller _always_ sees user-scope helper, and
my problematic application works fine, and it did for the last couple
of months.

So my suspection here is: Rails 1.1 is "lazy" in loading helpers, and
Rails 1.0 is not. Or it is my fault and I've always should prefix my
call with the :: in the admin-scope code?
If all my observations are not a crap and anybody is interested in
investigating it, I can prepare a step-by-step instruction how to
replicate a problem, with a test code (simple placeholder code, that
is).

--

RafaÅ? Komorowski
removed_email_address@domain.invalid
GG: 4083718
<http://homepage.mac.com/komor/iblog/>
RafaÅ? Komorowski (Guest)
on 2006-04-26 12:11
(Received via mailing list)
Everybody seems to ignore my thread :-) so I will throw one last
question: is it wrong to call objects/methods defined in helper from
the controller code?

--

RafaÅ? Komorowski
removed_email_address@domain.invalid
GG: 4083718
<http://homepage.mac.com/komor/iblog/>
Chris T (Guest)
on 2006-04-26 12:27
(Received via mailing list)
RafaÅ? Komorowski wrote:
> _______________________________________________
> Rails mailing list
> removed_email_address@domain.invalid
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
Just to show it's not being ignored (and speaking as a
not-completely-got-my-head-around-OO-yet-ex-PHPer), I *think* that
helpers are supposed to be called from views. From the API:

    The template helpers serve to relieve the templates from including
    the same inline code again and again. Itâ??s a set of standardized
    methods for working with forms (FormHelper), dates (DateHelper),
    texts (TextHelper), and Active Records (ActiveRecordHelper) thatâ??s
    available to all templates by default.

    Itâ??s also really easy to make your own helpers and itâ??s much
    encouraged to keep the template files free from complicated logic.
    Itâ??s even encouraged to bundle common compositions of methods from
    other helpers (often the common helpers) as theyâ??re used by the
    specific application.

I am struggling slightly (and I think it's mainly me failing to 100% get
my head around the OO bit) where you then put methods used by controller
actions (in that controller, in application.rb, in /lib, or, I suspect,
to analyse things better so they better fit into MVC).

Not sure this helps...
RafaÅ? Komorowski (Guest)
on 2006-04-26 12:41
(Received via mailing list)
On 26/04/2006, at 10:28, Chris T wrote:

> Just to show it's not being ignored (and speaking as a not-
> completely-got-my-head-around-OO-yet-ex-PHPer),

Thanks Chris :-D

> I *think* that helpers are supposed to be called from views. From
> the API:

Yes, I've read this in the Rails book, too. But I have some data-
structures that seem to be both model-related, and view-related. Some
popup menus that are commonly built in the views, you know: project-
type, custom month-list or whatever. Should I just move them to the
model? Or to the controller, better yet.


--

RafaÅ? Komorowski
removed_email_address@domain.invalid
GG: 4083718
<http://homepage.mac.com/komor/iblog/>
Tom M. (Guest)
on 2006-04-26 19:20
(Received via mailing list)
On Apr 26, 2006, at 1:40 AM, RafaÅ? Komorowski wrote:

> Yes, I've read this in the Rails book, too. But I have some data-
> structures that seem to be both model-related, and view-related.
> Some popup menus that are commonly built in the views, you know:
> project-type, custom month-list or whatever. Should I just move
> them to the model? Or to the controller, better yet.

Helpers are perfect for popups. I use helpers like this, but I have
them return just the data the built-in helper needs so the view is
very easy to understand and adjust:

   def born_on_start_year
     Time.now.years_ago(18).year
   end

   def born_on_end_year
     Time.now.years_ago(100).year
   end

   def gender_select
     [ [ 'Male',  'M'],
       [ 'Female','F'] ]
   end

   <span class="label">Gender:</span><br/>
   <%= select 'buyer', 'gender', gender_select %><br/>
   <span class="label">Birthday:</span><br/>
   <%= date_select 'buyer', 'born_on', :start_year =>
born_on_start_year, :end_year => born_on_end_year, :order =>
[:month,:day,:year] %><br/>

If they're in more than one view, put them in application_helper.rb

These particular helpers don't need models, but here's one that does:

   def unit_select
     Unit.find(:all,
               :order => 'seconds').map {|u| [u.name, u.id]}
   end

   <%= select 'seller','unit_id', get_units %><br/>

--
-- Tom M.
This topic is locked and can not be replied to.