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 recall #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.
Related
I want to render a few instances of Post object on a single page.
Currently I have in my controller the code:
#post = Post.find(1)
and in the index view I have:
<%= render :partial => 'posts/post', :object => Post.find(1) %>
Now I want to print the second instance, how to do it? This code for the second instance does not work.
<%= render :partial => 'posts/post', :object => Post.find(2) %>
Couple of things:
When you set instance variable (prefixed with #) in your controller, they're available in your views. So you could do something like:
<%= render :partial => 'posts/post', :object => #post %>
Generally, index actions are meant to deal with a collection (#posts). I'd expect something like:
#posts = Post.where(author: current_user)
If you want to display a post identified by an id, I'd recommend taking a look at CRUD operations: https://guides.rubyonrails.org/routing.html#resources-on-the-web
Roughly, what you may want to do is something like:
# config/routes.rb
resources :posts
# app/controllers/posts_controller.rb
def show
#post = Post.find(params[:id])
end
# app/views/posts/show.html.erb
<%= render partial: 'posts/post', locals: { post: #post } %>
Remember that controllers sets the instance variables, and views use them
I am trying to render my questions form partial on my posts show page. Right now when i enter text and press post it redirects to the default form and keeps the text.
I am rendering the form like so:
<%= render :partial => "questions/form", :locals => {:question => #comment.questions.new} %>
The questions controller:
def create
#comment = Comment.find(params[:comment_id])
#question = #comment.questions.new(question_params)
end
the form:
<%= simple_form_for [#comment, Question.new] do |f| %>
<%= render :partial => "questions/form", :locals => {:question => #comment.questions.new} %>
this part , :locals => {:question => #comment.questions.new} seems to be useless cause you override it anyway in the form partial with Question.new in the simple_form_for.
create action should have a save call and redirect to somewhere if save successfull or not.
def create
#comment = Comment.find(params[:comment_id])
#question = #comment.questions.new(question_params)
if #comment.save
redirect_to :back
else
# somet actions here
end
end
in my group controller I have two methods:
def new
#group = Group.new
respond_to do |format|
format.js
end
end
def new_beta
#group = Group.new
respond_to do |format|
format.js
end
end
I have a form that starts like so:
<%= form_for Group.new, :remote => true do |f| %>
How can I get the form_for to post to the new_beta controller? Thanks
You can set :
<%= form_for Group.new, :url=>{ :action =>"new_beta", :controller =>
"group"}, :remote => true do |f| %>
(you can also -preferably- directly use a named route instead of ":url => ")
First this is bad practice but..
in your routes add
resources :groups do
member do
get :new_beta
post :new_beta_create
end
end
Now
<%= form_for Group.new, :url => new_beta_create_groups_path, :remote => true do |f| %>
However I recommend creating a new controller called something like: alternate_groups_controller. Even better make a namespace for them.
Good luck
I have a simple partial to show some topics from the associated community
<%= render :partial => 'shared/topic', :collection => #community.topics %>
I'm trying to make a mobile version of the site, and to not render the partial to the same view, but to a new view.
I tried something like this
def topicsCommunity
fetch_topics ["community_id = ?", #community.id]
render :action => 'index'
end
But I can't get the community.id from my community view.
Also tried this :
#topicscommunity = #community.topics.find(:all,
:conditions => {:community_id => #community.id})
But from the topics_Controller, it didn't work.
Thanks for the help.
You don't have to use render :partial => ... in views only. You can easily do it in your controller (instead of render :action => ... or whatever).
So, just put this in the end of your controller
render :partial => 'shared/topic', :collection => #community.topics
There's no fundamental difference between calling render with :action, :partial, :text, :template or any other hash key.
If you just want to render the same template, use:
def topicsCommunity
fetch_skills ["community_id = ?", #community.id]
render 'index'
end
I am working through a tutorial with the following code:
<h3>New Comment</h3>
<%= render :partial => #comment = Comment.new,
:locals => { :button_name => "Create" } %>
I believe that 'render :partial => #comment' works like 'render :partial => "comment", :object => #comment'
Where does ' = Comment.new' fit in?
Is it shorthand for :object?
Alan
In Ruby terms,
#obj = Object.new # returns #obj
So you're rendering a comment partial and creating a new comment object that it can work with at the same time.
See http://apidock.com/rails/ActionView/Partials section "Rendering objects with the RecordIdentifier":
# <%= render :partial => "accounts/account", :locals => { :account => #buyer } %>
<%= render :partial => #account %>
Though documented, this is hardly used. The new+assignation (as explained by aharon) works, but it seems a bit tricky. In a tutorial you would expect to find a more orthodox approach:
Create objects in controllers not in views.
Use render :partial => 'mypartial', :locals => {...}