Hello,


I'm creating a Rails app on top of a legacy document management 
system.  I'm looking for a way to force an ApplicationController's 
:before_filter method to execute before the ActiveRecord model is evaluated:


class *Document* << ActiveRecord::Base

  acts_as_controlled

end


My acts_as_controlled() method generates different SQL criteria & bindings 
for scopes and finders based on the state of the Document and whether it's 
checkout out by the current user (MGR.user) vs checked out by another user, 
vs checked in.  The model's default_scope matches the check in, checked 
out, or working copy accordingly to provide the correct records.


The legacy application uses basic http auth and my rails application is 
deployed in the same context, so I obtain MGR.user from the http request 
using :before_filter:


class *ApplicationController* < ActionController::Base

  before_filter :authenticate

  def authenticate

        auth_data = Base64.decode64(request.authorization.split(' ', 
2).last || '').split(/:/, 2)

        MGR.user=auth_data[0]

        MGR.pass=auth_data[1]

   end

end


class *DocumentsController* < ApplicationController

  def index

    @documents = Document.all

    respond_to do |format|

      format.html # index.html.erb

      format.json { render :json => @documents }

    end

  end

end



This authentication works only if the first request goes to a controller 
that doesn't use an ActiveRecord model that  acts_as_controlled.  If the 
initial request goes to DocumentController, the Document model is loaded 
and acts_as_controlled is called *before* ApplicationController's 
:before_filter can set MGR.user:


Started GET "/MyApp/documents" for 127.0.0.1 at Thu Jul 26 18:05:52 -0700 
2012


NativeException ([from a java method of the legacy application]):

  config/initializers/myapp.rb:169:in `current_user'

  config/initializers/myapp.rb:351:in `define_model_scope'

  config/initializers/myapp.rb:625:in `acts_as_controlled'

  app/models/document.rb:2:in `Document'

  app/models/document.rb:1:in `(root)'

  app/models/document.rb:456:in `load_file'

  app/controllers/documents_controller.rb:1:in `(root)'

*  app/controllers/documents_controller.rb:456:in `load_file'*


Rendered 
vendor/bundle/jruby/1.8/bundler/gems/rails-80f6547f5b25/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
 
(27.0ms)

Rendered 
vendor/bundle/jruby/1.8/bundler/gems/rails-80f6547f5b25/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
 
(3.0ms)

Rendered 
vendor/bundle/jruby/1.8/bundler/gems/rails-80f6547f5b25/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
 
within rescues/layout (46.0ms)


One solution would be to short-circuit acts_as_controlled if MGR.user isn't 
set, store a reference to the model, and finally execute acts_as_controlled 
on all referenced models at the end of the :before_filter method, but that 
approach would mean evaluating each model twice.


Is there a better way to make ApplicationController :before_filter execute 
before the Document model is evaluated by DocumentController?


PS:  Also, is it even safe to store the user id in a constant like MGR?  I 
haven't seen any warnings about it being redefined so far, but I'm not 
quite sure how rails instances are managed across requests & sessions with 
JRuby and Tomcat.  


Thanks in advance for your advice.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msg/rubyonrails-talk/-/W6C4BcdlFB0J.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to