undefined method 'each' when accessing articles from navbar in rails app - ruby-on-rails

I need to be able to access articles through the navbar dropdown.
in my views/application/_navbar.html.erbI have the code snipped below. It is not working and I always get this error undefined method 'each' for nil:NilClass
when I hit the link in the dropdown the app goes to the right path http://localhost:3000/lcas/1
I only need to be able to access the first article in each category so http://localhost:3000/lcas/1 is the right path for the first link in the dropdown
code from views/application/_navbar.html.erb
<ul class="dropdown-menu">
<% #lcas.each do |lca| %>
<li><%= link_to lca.title, lca_path(lca) %></li>
<% end %>
<% #energy_analyses.each do |energy_analysis| %>
<li><%=link_to energy_analysis.title, energy_analysis_path(energy_analysis) %></li>
<% end %>
<% #green_accountings.each do |green_accounting| %>
<li><%= link_to green_accounting.title, green_accounting_path(green_accounting) %></li>
<% end %>
<li class="divider"></li>
<li>Something</li>
<li class="divider"></li>
<li>something</li>
</ul>
On my index.html.erbI have basically the same code and there it works.
<% #lcas.each do |lca| %>
<div class="col-md-4 col-xs-12">
<span class="glyphicon glyphicon-tasks icons" aria-hidden="true"> </span>
<div class="panel-heading">
<h3 class="panel-title"><%= link_to lca.title, lca_path(lca) %></h3>
</div>
</div>
<% end %>
I've tried to add
#lcas = Lca.all
#energy_analyses = EnergyAnalysis.all
#green_accountings = GreenAccounting.all
to the application_controller.rb but with out any success.
here is the lcas_controller.rb
class LcasController < InheritedResources::Base
private
def lca_params
params.require(:lca).permit(:title, :body, :image)
end
end
It would be very nice if someone could guide me through this.

You probably need few things:
Set a before_action method for those variables in application_controller.rb to make sure each other controller calls it and pass the variable to their corresponding view:
before_action :set_vars
def set_vars
#lcas = Lca.all
#energy_analyses = EnergyAnalysis.all
#green_accountings = GreenAccounting.all
end
Now you should be able to access #lcas from your partial, but using instance variables in partials is violating MVC, so you should pass locals to it:
<%= render 'application/navbar', :lcas => #lcas %>
Not sure how to pass multiple locals, maybe like this:
<%= render 'shared/navbar', locals: {:lcas => #lcas, :energy => #energy_analyses, :green => #green_accountings} %>
And of course, don't use # in partial if passing locals:
<% energy.each do |energy_analysis| %>

Related

Recurring Action template error ruby on rails

I keep on having this error
ActionView::Template::Error (undefined method `each' for nil:NilClass):
Here's my show.html.erb
<% #bookings.each do |booking| %>
<% if booking.checkin_on > Date.today %>
<% if booking.status == "Confirmed" %>
<li class="dashboard">
<%= cl_image_tag(booking.bed.photo.path, width: 400, height: 300, crop: :fill, class: "pdt-image hidden-xs" ) %>
<div class='product-body'>
<h2><%= booking.bed.title %></h2>
<p>City: <strong><%= booking.bed.city %></strong></p>
<p>Address: <strong><%= booking.bed.address %></strong></p>
<p>Total price: <strong><%= booking.value %> €</strong></p>
</div>
<div>
<ul class="list-unstyled hidden-sm hidden-xs padded">
<li><strong>Your booking is confirmed !</strong></li>
<li class="text-right"><%= link_to "Delete this booking", booking_path(booking), method: :delete, class:"btn btn-default", data: {confirm: "Are you sure"} %> </li>
</ul>
</div>
</li>
<% end %>
<% if booking.status == "Canceled" %>
<li class="dashboard">
<%= cl_image_tag(booking.bed.photo.path, width: 400, height: 300, crop: :fill, class: "pdt-image hidden-xs" ) %>
<div class='product-body'>
<h2><%= booking.bed.title %></h2>
<p>City: <strong><%= booking.bed.city %></strong></p>
<p>Address: <strong><%= booking.bed.address %></strong></p>
<p>Total price: <strong><%= booking.value %> €</strong></p>
</div>
<div>
<ul class="list-unstyled hidden-sm hidden-xs padded">
<li><p><%= booking.bed.user.first_name%> canceled your booking </p></li>
</ul>
</div>
</li>
<% end %>
<% end %>
<% end %>
And here's my my_bookings controller
class My::BookingsController < ApplicationController
def index
#bookings = Booking.where(user_id: current_user.id)
#bookings = Booking.all
#beds = Bed.all
end
def show
set_booking
#bed = #booking.bed
end
private
def set_booking
#booking = Booking.find(params[:id])
end
end
Any suggestions? Or anything I can't see? I have tried almost everything I can think of at the moment. Thanks!
You are not declairing the #bookings variable on your show method, which explains the crash. It appears you are declaring it as you wanted it on the first line of your index method. Just change where you declare it, and it shall be alright.
Also, to avoid further headaches, you should refactor the set_booking method to:
def set_booking
#booking = Booking.find_by(id: params[:id])
end
by deafult .find() will crash your view if it doesn't find anything
.find_by, on the other hand, will return an empty answer, so it won't crash. Also, it's more versatile, since this way you can search from innumerous other variables set in your model, i.e. name.
By convention in Rails controller actions (index and show in your case) render views with same names, in your case those might be intex.html.erb and show.html.erb. In your show method you define two variables: #bed and #booking and in your view (show.html.erb) you try to loop variable #bookings which you have not defined in your controller action. Thus, you are getting this error.
Looks like you need to rename show.html.erb to index.html.erb as you are listing bookings and their information in it.

Render an attributes of each object - Rails

I have a view right now that renders an object on the page. The object is an Integration. On the Integration object I have attribute called filters. Filters are stored as an array. All I need to do is list out the filters of each integration below them in a list. Here is my code.
View
<% if #integrations.any? %>
<div class="configured-integrations">
<h3 class="heading-3">My Configured Integrations:</h3>
<ul class="integration-list integration-list--compact">
<%= render #integrations %>
</ul>
</div>
<% end %>
Screenshot
In the screenshot you can see that each of those elements are integrations. I need to list the filters of each integration below the title there.
Controller
def index
# Get the list of the user's integrations grouped first by provider then
# from oldest to newest."
#integrations = current_account.integrations
.order(type: :asc, created_at: :asc)
end
I hope this is clear enough. So recap: I need to list the filters on each integration below. I've already tried stuff like this #integrations.first.filters but that wont work because it's a static call. I need something like a list. Thank you
You can add another partial to render all filters which are associated with your Integration.
Create a partial file _show_filters.html.erb in your views
<% filters.each do |filter| %>
<li><%= filter %></li>
<% end %>
And render this partial while iterating through your #integration object like this.
<% if #integrations.any? %>
<div class="configured-integrations">
<h3 class="heading-3">My Configured Integrations:</h3>
<ul class="integration-list integration-list--compact">
<% #integrations.each do |integration| %>
<li>
<%= integration %>
<ul class="">
<%= render 'show_filters', filters: integration.filters %>
</ul>
</li>
<% end %>
</ul>
</div>
<% end %>
What you need to iterate through each integration, then <%= render integeration.filters %>
<% if #integrations.any? %>
<div class="configured-integrations">
<h3 class="heading-3">My Configured Integrations:</h3>
<ul class="integration-list integration-list--compact">
<% #integrations.each do |integration| %>
<li>
<%= integration %>
<ul class="">
<%= render integration.filters %>
</ul>
</li>
<% end %>
</ul>
</div>
<% end %>
You will have to update this code to make the partials work, but i hope this gets the idea across.
You can't use the shortcut <%= render #integrations %> here, because you want a subgroup inside #integrations. So you'll have to do it the long way.

How do I print validation messages for form_for :post structure?

I have something like
<div class="userInput">
<%= form_for :scribble do |f| %>
<%= f.text_area :scribble, cols: 65, rows: 4,:maxlength => 255%>
<%= f.submit %>
<% end %>
</div>
1)My Scribble model has min and max character length validation, now how do I print the error messages here. If it is an instance variable I know how to print, but this is a symbol.
2) This code is present in the application.html.erb. I am not able to understand how do I move it into a view of Scribble controller other than appliation. Problem is this form is not independent, it is a part of action index display of controller Scribbles,(and the form should be displayed always) and action index is already doing listing of scribbles.
Controller
def index
#scribbles = Scribble.order("scribbles.scribble DESC").all
end
def show
end
def new
end
def create
#scribble = Scribble.new(profile_params)
#scribble.likes =#scribble.dislikes =#scribble.shares=0;
#scribble.save
#scribbles = Scribble.order("scribbles.scribble DESC").all
render :index
end
Here how i out-put any errors or validation messages:
Controller:
def create
#scribble = Scribble.new(profile_params)
#scribble.likes =#scribble.dislikes =#scribble.shares=0;
if #scribble.save
flash[:notice] = "Scribble is successfully created"
redirect_to root_url
else #
render 'index'
end
end
Views:
Create a partial to show error messages if any e.g _error_messages.html.erb
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert callout text-center" data-closable>
<p><strong>This form contains <%= pluralize(object.errors.count, 'error') %>.</strong></p>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<button class="close-button" aria-label="Dismiss alert" type="button" data-close>
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<% end %>
Render errors:
Now you can call <%= render 'layouts/error_messages', object: #scribble %> and put it anywhere in your views to render the errors validation. note: the object is passed, so it can be re-use to any form. credits to Hartl Tutorial.

Using multiple yields to insert content

I am trying to insert content on my page with yield but every time action removes whole content from the page. I have one main yield which is working fine:
<body>
<%= render 'layouts/header' %>
<div class="container">
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</body>
But inside that new content which is displayed on one page I have another yield:
<div class="container">
<%= render 'admins/menu' %>
<%= yield :admin %>
</div>
When user clicks on the menu which is rendered, new content should be displayed below that menu.
admins/_menu.html.erb
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<ul class="nav">
<li><%= link_to "Users", :controller => "admins", :action => "test" %></li>
<li><%= link_to "1", ... %></li>
<li><%= link_to "2", ... %></li>
<li><%= link_to "3", ... %></li>
</ul>
</div>
</div>
</div>
Controller:
class AdminsController < ApplicationController
def index
end
def test
#users = User.paginate(page: params[:page])
end
end
test.html.erb
<% content_for :admin do %>
<h1>All users</h1>
...
<% end %>
When I click on the option 'Users' from menu, page refreshes, menu disappears and nothing is displayed inside `body'. I want the content to be displayed below menu. How to use that second yield and accomplish this functionality?
I hope the question is not confusing. If question is confusing, please write me in comments and I will edit it immediately.
Thank you :)
So, when you go to the index page you will get the piece of html that will be placed in the main layout, and this piece of html look like this:
<div class="container">
<%= render 'admins/menu' %>
<%= yield :admin %>
</div>
This code will yield :admin properly.
When you go to the test page you do not have this html code anymore (since it only belongs to the index method). So, anything you put in the content_for(:admin) block will be ignored since no-one is printing it.
What you probably want to do is creating a shared layout for all your admin pages. Follow this guide and you'll have your solution.
Solution
Edit the application.html.erb layout using this:
<%= content_for?(:content) ? yield(:content) : yield %>
instead of
<%= yield %>
Then create an admins.html.erb file inside the layouts folder to handle your admin pages' layout. Something like this:
<% content_for :content do %>
  <div class="container">
<%= render 'admins/menu' %>
<%= yield %>
</div>
<% end %>
<%= render template: "layouts/application" %>
Will do fine. Then in the index.html.erb and test.html.erb just place regular HTML content, without using the content_for(:admin) block. Everything should work fine and you'll have your custom admin template, with a slightly different look from regular pages.
Calling yield doesn't work in helper modules, while content_for does, so you should replace your yield calls in the helper files.
Also noteworthy: using provide is recommended over content_for when you're only using the method in 1 place instead of multiple places. You'll get better performance since it won't leave the buffer open while looking for more content, and your intent will be clearer to other developers that may see your code. (see http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-provide)
I found that you have to add an yield (without actually outputing) before the namespaced tags.
<div>
<% yield %>
<div class="mt-3">
<div class="text-2xl tracking-wide font-bold text-gray-900">
heading
<%= yield :heading %>
</div>
</div>
<div class="relative bg-white rounded-xl shadow-xl mb-8 min-h-28">
<%= yield %>
</div>
...

update partial with object content in rails 4

Well, i have a problem, and i was wondering if it could be solved with rails only.
I have setup a view (home.html.erb) vith 3 partials, like this:
<%provide :title, 'Reader'%>
<div class = "row">
<div class = "span4">
<div class = "row">
<%= render 'layouts/add_subscription'%>
</div>
<div class = "row">
<%= render 'layouts/subscription_list'%>
</div>
</div>
<div class = "span8">
<div class = "row">
<%= render 'layouts/view' %>
</div>
</div>
</div>
where subscription_list shows up a list of links pointing to the list action after a redirection, each of them with the id of the subscription:
<ul>
<% current_user.subscriptions.each do |s| %>
<li><%= link_to s.url, "/list?s_id=#{s.id}" %></li>
<% end %>
</ul>
So, each of these links points to the list action in the controller, which tries to fetch the feed list of the subscription just clicked, and update the home view with the list of titles for the selected subscription:
def list
s_id = params[:s_id]
feed = ""
if !s_id.blank?
s = Subscription.find_by(id: s_id)
feed = Feedzirra::Feed.fetch_and_parse(s.url)
#render partial: "layouts/view", :locals => {:f => feed}
end
The problem is that I'm stuck at this point. I've tried to do a redirect_to home_path with feed as a parameter, and even a render (the line before the end of the list method) to see what happened, but nothing updates 'just' the layouts/view partial:
<ul>
<% if defined? feed and !feed.blank? %>
<% f.entries.each do |entry|%>
<li><%= entry.title %></li>
<% end %>
<% end %>
</ul>
So, I was wondering if it's possible to update the partial and see the result after a page reload using only rails methods, or if it can/must be done using javascript, and a clue to how to do this. Thanks in advance.
The goal you want to achieve is to show feed entries in the home.html.erb after clicking a link.
You can do it by pointing your links to the home action instead of list so that rails will automatically render your home.html.erb view and
you have to assign the instance variable #feed so it will be visible in your view.
You can do it like this (refactored a bit):
controller
def home
s_id = params[:s_id]
if s_id.present?
s = Subscription.find_by(id: s_id)
#feed = Feedzirra::Feed.fetch_and_parse(s.url)
end
end
layout/view
<ul>
<% if #feed.present? %>
<% #feed.entries.each do |entry|%>
<li><%= entry.title %></li>
<% end %>
<% end %>
</ul>
I'm not sure what is the path to your action, I assume here that home is the root ("/")
layouts/subscription_list
<ul>
<% current_user.subscriptions.each do |s| %>
<li><%= link_to s.url, "/?s_id=#{s.id}" %></li>
<% end %>
</ul>

Resources