开发者

Trouble on rendering a template passing a local variable

I am running Ruby on Rails 3 and I would like to render a template (show.html.erb) passing a local variable.

In RAILS_ROOT/views/users/show.html.erb I have

Name: <%= @user.name %>
Surname: <%= @user.surname %>

I have also a page controller to handle pages and in the application_controller.rb an istance of @current_user. A page is called user, so in RAILS_ROOT/views/pages/user.html.erb I have

<%= render :template => "users/show", :locals => { :user => @current_user } %>

The above code doesn't work (I get this error: RuntimeError in Pages#user, Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id) but this works:

<%= render :template => "users/show", :locals => { :user => @user = @current_user } %>

I think it is not a good approach to "overwrite" the @user variable. This is because, for example, if I need to recal开发者_StackOverflow中文版l @user after the above 'render' statement it will don't work anymore.

So, what is a solution in order to render show.html.erb?


I tryed also

<%= render :template => "users/show", :locals => { @user => @current_user } %>
<%= render :template => "users/show", :locals => { :object => @current_user, :as => @user }

but those don't work.


UPDATE

If in pages_controller.rb I put this

def user
  @user ||= @current_user
end

it will work and in the view files you can just use

<%= render :template => "users/show" %>

Anyway, I discoverd that I have this error (see below for more info):

ActionController::RoutingError in Pages#user
No route matches {:action=>"destroy", :controller=>"users"}

The error is generated from this form statement located in a partial loaded from show.html.erb:

<%= form_for(@user, :url => user_path) do |f| %>
  ...
<% end %>


:locals => { :user => @current_user }

and in template

Name: <%= user.name %>

Local variables are local, so you don't need @ to refer them.

@user502052
You can render view explicitly from your controller.

render :template => "users/show", :locals => {...}

When you don't execute render in controller, framework does that for you with default parameters. When you do, you can specify different template file, pass local variables, render a partial: anything render function supports.


Just in case you are NOT rendering a partial, and do not want to use :template option, this can also be done in Rails 4 with:

render 'users/show', {user: @current_user}


Url:

http://localhost/pages/user

this will call the user method on pages_controller. You have this:

def user
  @user ||= @current_user
end

Rails creates an instance variable @users and by default will try to render a view template at app/views/pages/user.html.erb. If that is not what you want, you have to say so in the controller:

def user
  @user ||= @current_user
  render :template => "users/show", :locals => { :user => @current_user }
end

This will now render app/views/users/show.html.erb with a local variable called user instead of the default app/views/pages/user.html.erb.

Currently you are waiting until you are inside a view template and then asking to render another view template. Once you are in a view template you should only need to render partial templates:

render :partial => 'users/show', :locals => {:user => @current_user}

Hopefully that helps clarify.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜