Login form as popup modalbox (only the rails part)

While redesigning an existing application, I’ve stumbled on a problem.

A number of links on the site requires that the user logs in. This is
currently solved by the simple (example)

<%=link_to ‘Upload image’, :controller => ‘image’, :action => ‘new’ %>

and in the ImageController I place a

before_filter :login_required, :only => :new

(login_required checks the session userdata, and redirects to a
login-page if necessary)

I want to change it at bit, so that when the user clicks the link - and
a login is actually required - a modalbox popup containing a login form
pops up on the same page as where the user clicked on the link

My issue is how to detect if the controller/action requires a login?

I am working on the concept to do something like this in the view

<%=protected_link_to ‘Upload image’, :controller => ‘image’, :action =>
‘new’ %>

and in the helper:

def protected_link_to(caption, options = {}, html_options = {})
if
var url = url_for(options)
return link_to_function caption, “show_login_popup(…blabla…,
{continue_url: url});”
end

return link_to caption, options, html_options
end

Question is: How do I implement the if

Thanks

  • Carsten

My issue is how to detect if the controller/action requires a login?

I think you’re going to have a fair bit of monkeying around to do.

A hint in the right direction is you can do this:

controller = “#{options[:controller]}_controller”.camelize.constantize
controller.filter_chain.map(&:method)

There’s probably a better way of doing step 1, in case you have
namespaced
controllers or something, but still.

Once you have the filter methods (from step 2) you can iterate over them
and
see if your login_required filter is present. You may have to do some
more
monkeying in the options in each of the objects returned by filter_chain
to
check for :only and :except options and handle those.

If you are linking to a URL rather than a :controller/:action pair you
may
want to use something like this in step 1:

controller_name =
ActionController::Routing::Routes.recognize_path(path)[:controller]

Anyway, it’s going to be quite deep/tricky, but that may give you a
nudge in
the right direction. Post back if you need more help.

Cheers,

Andy

OK, so I had a bit more of a play. You’ll still need to do this:

controller = “#{options[:controller]}_controller”.camelize.constantize

But if you create a file in config/initializers called
“action_filtered.rb”
and put this in it:

class ActionController::Base
def self.action_filtered?(action_name, filter_name)
action_name = action_name.to_s
filter_chain.each do |filter|
if filter.method == filter_name
if filter.options[:only].respond_to?(:include?)
if filter.options[:only].include?(action_name)
return true
end
elsif filter.options[:except].respond_to?(:include?)
if !filter.options[:except].include?(action_name)
return true
end
else
return true
end
end
end
false
end
end

You’ll then have a method on a controller so you can do this:

controller = “#{options[:controller]}_controller”.camelize.constantize
login_required = controller.action_filtered?(options[:action], :
login_required)

And login_required will be a boolean value as to whether the
login_required
filter is effective for that action.

You will probably want to wrap that up in to a method somewhere neater
and
you’d need to consider that the user may already be logged in (in which
case
you don’t want the popup), but it may help you get started.

Cheers,

Andy

Andy J. wrote:

OK, so I had a bit more of a play. You’ll still need to do this:

This (and the previous reply) is exactly what I needed! Thanks a bunch
:slight_smile:

You will probably want to wrap that up in to a method somewhere neater
and
you’d need to consider that the user may already be logged in (in which
case
you don’t want the popup), but it may help you get started.

Yes I am going to

  1. put it into a helper
  2. Let the routing configuration help to decipher controller and action
    name (since I have a mix of link_to calls with straight urls,
    controller/action hashes and rest routes)
  3. Check for if the user is already logged in.

This is really great - you rock!

  • Carsten