In my activities view I use a content_for like this:
<% content_for :activities do %>
<div id="contentblock">
<div class="content_title general"></div>
<ul id="updates">
<% #activities.each do |activity| %>
<li><%= activity.created_at.in_time_zone.strftime("%d-%m-%Y # %H:%M") %><br /><%= activity.activity %></li>
<% end %>
</ul>
</div>
<% end %>
And in the application layout I want to show this by doing this:
<% if content_for?(:activities) %>
<%= yield :activities %>
<% end %>
However, it only shows if the activities view is active, not in others views. Why is that?
Related
Say I have 2 erb views: a list view and a show view, I want to render the show view inside the list view
list view
<% #vehicles.each do |vehicle| %>
<h2><%= vehicle.type %></h2>
<ul>
<% vehicle.accessories.each do |accessory| %>
<li><% accessory.title %></li>
<% end %>
</ul>
<% end %>
show view
<h2><%= #vehicle.type %></h2>
<ul>
<% #vehicle.accessories.each do |accessory| %>
<li><% accessory.title %></li>
<% end %>
</ul>
the issue is the show view takes an #vehicle instance variable, how can I pass that down from the parent if I was going to nest these and it still shows up as an instance variable, accessed with #vehicle? something like:
<% #vehicles.each do |vehicle| %>
<%= render "show" %>
<% end %>
I guess you might want to make that show view a partial. Something like:
<h2><%= vehicle.type %></h2>
<ul>
<% vehicle.accessories.each do |accessory| %>
<li><% accessory.title %></li>
<% end %>
</ul>
Then you can do something like:
<% #vehicles.each do |vehicle| %>
<%= render "path/to/show_partial", locals: {vehicle: vehicle} %>
<% end %>
Naturally, you'll want to:
use the real path/to/show_partial, whever that happens to be, and
do some eager loading so that you're not doing a whole bunch of N+1 queries.
I have my application.html.erb file where this code located:
<% if notice %>
<p class="notice"><%= notice %></p>
<% elsif alert %>
<p class="alert"><%= alert %></p>
<% end %>
<%= devise_error_messages! %>
All is great, but form validations are made by using (as usual), this:
<%= form_for #project do |f| %>
<% if #project.errors.any? %>
<h2><%= pluralize(#project.errors.count, "error") %> prevented this project from saving:</h2>
<ul>
<% #project.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
...
<% end %>
How to include them into main app page & show them always in top?
How to include them into main app page & show them always in top?
This is deeper than just adding a partial (as Umang Raghuvanshi suggested).
The problem is that the errors method is part of an #object, which means you have to make sure you're able to access this object whenever you want to output the errors in application.html.erb.
Partials should never be dependent on #instance_variables - they're meant to be loaded in any part of your app. You can pass local variables to them, allowing you to send predefined data as you need.
In your case, I would use a partial but populate it with a content_for:
--
This is what I'd do:
#app/views/layouts/application.html.erb
<%= render partial: "shared/errors" %>
#app/views/shared/_errors.html.erb
<%= content_tag :div, class: "errors" do %>
<% if errors.try?(:any?) %>
<% errors.full_messages.each do |msg| %>
<%= content_tag :li, msg %>
<% end %>
<% else %>
<% flash = %w(notice error alert) %>
<% flash.each do |f| %>
<%= content_tag :div, class: f, flash => [f.to_sym] if flash[f.to_sym] %>
<% end %>
<%= devise_error_messages! %>
<% end %>
<% end %>
#app/views/projects/new.html.erb
<%= form_for #project do |f| %>
<%= render "shared/errors", locals: {errors: #project.errors} %>
<% end %>
This will allow you to style the .errors div to be absolutely position at the top:
JSFiddle
#app/assets/stylesheets/application.css
.errors {
display: inline-block;
width: 50%;
position: absolute;
top: 5%;
}
Extract the code into a partial and include it into your application.html.erb.
_your_partial_name.erb
<% if #project.errors.any? %>
<h2><%= pluralize(#project.errors.count, "error") %> prevented this project from saving:</h2>
<ul>
<% #project.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
application.html.erb
<%= render partial: 'your-partial-name' %>
<% if notice %>
<p class="notice"><%= notice %></p>
<% elsif alert %>
<p class="alert"><%= alert %></p>
<% end %>
<%= devise_error_messages! %>
You could also try using flash.
I'm trying to follow Ryan Bates Polymorphic association tutorial in order to put some comments to my site.
The thing is I have nested resources:
#Nesting Resources
resources :users do
resources :photos do
resources :comments
resources :tags
end
end
So I'm getting an error in my view (photos/show)
undefined method `each' for nil:NilClass
I suppose the problem is in my controller, with comments, that is not defined correctly, but since I have nested resources, I don't know how to do it.
Photos Controller
def show
#photo = Photo.friendly.find(params[:id])
#user = #photo.user
#commentable = #photo
#comments = #commentable.comments
#comment = Comment.new
end
New Comment Partial
<h2>Comments</h2>
<% if #comments.any? %>
<%= render "comments/comments" %>
<% else %>
TodavĂa no hay comentarios
<% if user_signed_in? %>
<%= render "comments/form" %>
<% end %>
<% end %>
Form partial (comments/form)
<%= form_for [#commentable, #comment] do |f| %>
<% if #comment.errors.any? %>
<div class="error_messages">
<h2>Please correct the following errors.</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.text_area :content, rows: 8 %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Comments partial (comments/comments)
<div id="comments">
<% #comments.each do |comment| %>
<div class="comment">
<%= simple_format comment.content %>
</div>
<% end %>
</div>
Your error says undefined method each for nil:NilClass. As you can guess you are calling each on a nil object. Here your #comments is nil and hence giving your trouble.
In your view try something like this:
<div id="comments">
<% if #comments %>
<% #comments.each do |comment| %>
<div class="comment">
<%= simple_format comment.content %>
</div>
<% end %>
<% end %>
</div>
Edit:
So if you look at your code you have #comments till here:
<% if #comments.any? %>
<%= render "comments/comments" %>
<% else %>
#do stuff
<% end %>
it's after you call your partial that your #comment is lost so try this:
<% if #comments.any? %>
<%= render "comments/comments", comments: #comment %>
<% else %>
#do stuff
<% end %>
and then in your view use
<div id="comments">
<% comments.each do |comment| %>
<div class="comment">
<%= simple_format comment.content %>
</div>
<% end %>
</div>
I'm building a Rails app up from the Sample App featured in Michael Hartl's book. In order to display error messages on user signup, I'm using a partial in the shared directory - app/views/shared/_error_messages.html.erb:
<%if #fact %>
<% #data = #fact %>
<% elsif #user %>
<% #data = #user %>
<% end %>
<% if #data.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#data.errors.count, "error") %>.
</div>
<ul>
<% #data.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Originally, this partial just started with something like:
<% if #user.errors.any? %>
However, since I've decided to re-use this partial to show errors on other pages, I'm having to use different objects (#user, #fact) depending on which page I'm using it on. This is easily solved by adding that IF statement at the top,
<%if #fact %>
<% #data = #fact %>
<% elsif #user %>
<% #data = #user %>
<% end %>
-but this feels icky. Is there a controller somewhere I should be putting this kind of logic for shared partials?
You can pass local variables to partial instead:
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
And in your template, for example:
<%= render 'shared/error_messages', object: #user %>
Marek's answer is probably the best. However, here is an alternative which though not scalable, is closer to what you have done.
Just replace:
<%if #fact %>
<% #data = #fact %>
<% elsif #user %>
<% #data = #user %>
<% end %>
with:
<% #data = #fact||#user %>
You could use render to point to the partial from your controllers for users and fact. Check out the API documentation on rendering partials.
I am trying to make a simpel treelistmenu with ancestry.
Here is my code in view and it is not working:
<ul>
<% for cat_opg in CatOpg.roots %>
<li> <%= cat_opg.navn %><li>
<% for cat_opg in CatOpg.children %>
<li> <%= cat_opg.navn %><li>
</ul>
<% end %>
</ul>
<% end %>
And my controller:
def liste
#cat_opg = CatOpg.find(:all)
end
I want to make this simpel tree menu as:
Root
-children
Root
-children
I dont know what i am doing wrong.
PS: I am a rails beginner
First of all, you are getting to model in view, not to local variable.
Second, you're rewriting variable.
It should be something like this:
<ul>
<% cat_opg.roots.each do |cat_opg_root| %>
<li> <%= cat_opg_root.navn %><li>
<% cat_opg_root.children each do |cat_opg_child| %>
<li> <%= cat_opg_child.navn %><li>
</ul>
<% end %>
</ul>
<% end %>
Alex thank you for your answer.
Now it works
Controller: #cat_opg = CatOpg
And the view:
<ul>
<% #cat_opg.roots.each do |cat_opg_root| %>
<li> <%= cat_opg_root.navn %></li>
<% unless cat_opg_root.children.empty? %>
<ul>
<% cat_opg_root.children.each do |cat_opg_child| %>
<li> <%= cat_opg_child.navn %></li>
<% end %>
</ul>
<% end %>
<% end %>
</ul>