Forum: Ruby on Rails two layouts for index action, or two index actions?

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.
A7a7dddca32cd8b6e5af394c500934d5?d=identicon&s=25 rv dh (ralph)
on 2007-07-31 17:52
Hello,

I'm working on a Rails application, and I want to keep things restful
and clean. I'm using the restful_authentication plugin to authenticate
users and I want to keep the administration backend separate from the
frontend. The application manages a list of items, let's say articles,
which are listed by the index action. The list of articles should be
visible in the frontend as well as in the backend, but frontend and
backend should show a different layout. I could switch the layout based
on the login status to keep things DRY, but this would show the backend
layout even if the client is logged in and wants to see the app from the
user's point of view. I could simply copy the index action from the
controller and rename it to list, which would even enable me to protect
the list action by restful_authentication and to leave the index action
public. But this approach does not keep things DRY.

Do you have any suggestions?
0f50b9a2ad85666d537d39bda49327ee?d=identicon&s=25 Jonathan Rochkind (jrochkind)
on 2007-08-01 03:57
Hmm, I'm confused. If the only thing that needs to be different is the
layout, why can't you just switch the layout inside the action, on a
per-request basis?

render :layout => "two"  # inside action method, perhaps in an 'if'
construct

I don't understand what you mean when you say "this would show the
backend layout even if the client is logged in..."

But if you really do need two separate actions for some reason, but
sharing the same code, there is an easy way to do that without repeating
yourself:

def first_action
  self.actual_logic()
end

def second_action
   self.actual_logic()
end

protected
def actual_logic
  # something goes here
end


If the two actions were to be in different controllers, you could use
inheritance or module mix-in to share the code between them, among many
other possible designs.

I'm not sure if this answers your question?

Jonathan

rv dh wrote:
> Hello,
>
> I'm working on a Rails application, and I want to keep things restful
> and clean. I'm using the restful_authentication plugin to authenticate
> users and I want to keep the administration backend separate from the
> frontend. The application manages a list of items, let's say articles,
> which are listed by the index action. The list of articles should be
> visible in the frontend as well as in the backend, but frontend and
> backend should show a different layout. I could switch the layout based
> on the login status to keep things DRY, but this would show the backend
> layout even if the client is logged in and wants to see the app from the
> user's point of view. I could simply copy the index action from the
> controller and rename it to list, which would even enable me to protect
> the list action by restful_authentication and to leave the index action
> public. But this approach does not keep things DRY.
>
> Do you have any suggestions?
A7a7dddca32cd8b6e5af394c500934d5?d=identicon&s=25 rv dh (ralph)
on 2007-08-03 00:18
Hello Jonathan,

Jonathan Rochkind wrote:
> Hmm, I'm confused. If the only thing that needs to be different is the
> layout, why can't you just switch the layout inside the action, on a
> per-request basis?
>
> render :layout => "two"  # inside action method, perhaps in an 'if'
> construct

That is because one action should be protected by
restful_authentication, which can restrict access on a
controller-action-base.

>
> I don't understand what you mean when you say "this would show the
> backend layout even if the client is logged in..."

What this means is the following: The layout of the frontend is
different from the layout of the backend. First I thought I could switch
the layout depending on the login status, somehow like this:

if logged_in?:
  render :layout => 'backend'
else
  render :layout => 'frontend'
end

Implementing this method, my client (the logged-in admin) would have to
log out each time he wanted to see the list of articles like normal
users do. I wanted to avoid this, so was searching for a 2-action
approach that still kept things DRY.

>
> But if you really do need two separate actions for some reason, but
> sharing the same code, there is an easy way to do that without repeating
> yourself:
>
> def first_action
>   self.actual_logic()
> end
>
> def second_action
>    self.actual_logic()
> end
>
> protected
> def actual_logic
>   # something goes here
> end

YES! This is exactly what I wanted. Sometimes I do not see the easiest
solutions, but that's what forums are for.

>
>
> If the two actions were to be in different controllers, you could use
> inheritance or module mix-in to share the code between them, among many
> other possible designs.
>
> I'm not sure if this answers your question?

It definately does. Thank you very much!

>
> Jonathan

Greetings, Ralph
This topic is locked and can not be replied to.