Render an attributes of each object - Rails - ruby-on-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.

Related

Splitting record set in Rails for display purposes in menu

I'm trying to split my records in half for display in my menu. The menu is two columns (col-md-4) but the methods I'm using with ODD number of records, puts the larger number on the wrong side (last_half) of my menu. What am I missing?
Menu
<div class="col-md-4">
<ul>
<li class="mega-menu-title">Products</li>
<% first_half(#menu_products).each do |product| %>
<li>
<%= link_to product_path(product) do %>
<span class="text-yellow"><%= product.name %></span> <%= product.subtitle %>
<% end %>
</li>
<% end %>
</ul>
</div>
<div class="col-md-4">
<ul>
<li class="mega-menu-title"> </li>
<% last_half(#menu_products).each do |product| %>
<li>
<%= link_to product_path(product) do %>
<span class="text-yellow"><%= product.name %></span> <%= product.subtitle %>
<% end %>
</li>
<% end %>
</ul>
</div>
<div class="col-md-4">
<!--- non-related code in last column in menu --->
</div>
Application Helper
def first_half(list)
list[0...(list.length / 2)]
end
def last_half(list)
list[(list.length / 2)...list.length]
end
You can use the following:
list.first((list.length/2).ceil) # will convert 1.5 to 2
And
list.last((list.length/2).floor) # will convert 1.5 to 1
The issue you had is that [7,8,9][3/2] returns 8, and the logic 3/2 (list.size / 2) was used in both first_half and last_half.
This is what I ended up doing to get it to work. I had to change the length to a float to_f, then I could get it to test in the console correctly.
def first_half(list)
list[0...(list.length.to_f / 2).ceil]
end
def last_half(list)
list[(list.length.to_f / 2).ceil...list.length]
end
Using .ceil on both methods then allowed the math to work.

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

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| %>

How to use yield with dashboard sidebar to show contents on same page

I have a rails app with a functionality quite similar to yelp with a dashboard for customers where they can edit their place but also change their acccount settings, etc. A customer can only have one place for now.
I've created a dashboard controller, views with a partial for the sidebar and everything is working so far but my problem is that when clicking on a link in the sidebar it yields to the application.html.erb. I want to yield everything from the sidebar to the main part of the dashboard/index.html.erb
So my question is how do I yield the things I click in my sidebar to the part on the right next to the sidebar on the page. Basically the functionality is like a navbar on top (only for logged in customers) but I get confused with two yields. I tried "content_for" and <%= yield :sidebar %> but didn't figure out how to get it working yet. Also I am using devise with a user and customer model which share the views and have the functionality for the customer to edit his user account in the dashboard sidebar which might cause a problem with "content_for"?
Please note that I am still learning ruby on rails and am very happy for any kind of input!
dashboard_controller.rb
def index
#place = Place.where(customer_id: current_customer.id).first
end
dashboard/index.html.erb
<div class="content">
<div class="sidebar">
<%= render 'dashboard/sidebar' %>
</div>
<div class="main">
<%= yield %>
</div>
</div>
_sidebar.html.erb
<li class="nav-link">
<%= link_to "<span class='fa fa-cog'></span> Edit".html_safe, edit_place_path(#place) %>
</li>
<li class="nav-link">
<%= link_to "<span class='fa fa-cog'</span> Settings".html_safe, edit_customer_registration_path %>
</li>
<li class="nav-link">
<%= link_to "<span class='fa fa-sign-out'></span> Log Out".html_safe, destroy_customer_session_path, method: :delete %>
</li>
application.html.erb
<body>
<%= render 'layouts/shared/header' unless #disable_navbar %>
<%= yield %>
<%= render 'layouts/shared/footer' unless #disable_footer %>
</body>
Within the context of a layout, yield identifies a section where content
from the view should be inserted.
http://guides.rubyonrails.org/layouts_and_rendering.html#understanding-yield
So no - yield will not "yield" to your dashboard/index.html.erb. Rather if you want it to have a different layout you should create a layout.
Lets look at an example:
<% # app/views/layouts/application.html.erb %>
<body>
<nav id="top-menu">
<h1><%= link_to 'MyApp', root_path %></h1>
<ul>
<%= yield :nav_links %>
<%# lets provide some default content for nav_links %>
<% content_for :nav_links do %>
<li><%= link_to 'Products', products_path %></li>
<% end %>
</ul>
</nav>
<div id="main">
<%= yield %>
</div>
</body>
Here we create a named yield in the layout called :nav_links and also add some "default" content with content_for :nav_links.
So lets look at what happens when we render /products/index.html.erb:
<div class="products">
<% if #products.any? %>
<%= render #products %>
<% else %>
<p>No products are available at this time</p>
<% end %>
</div>
<%# we also want to add a contextual navigation link %>
<% content_for(:nav_links) do %>
<li><%= link_to 'Sales', sales_path %></li>
<% end %>
The rendered result is:
<body>
<nav id="top-menu">
<h1>MyApp</h1>
<ul>
<li>Products</li>
<li>Sales</li>
</ul>
</nav>
<div id="main">
<div class="products">
<p>No products are available at this time</p>
</div>
</div>
</body>
Rails inserts the content from the view into the "main" layout and the content from content_for(:nav_links) is concatenated into the buffer.
Also I am using devise with a user and customer model which share the
views and have the functionality for the customer to edit his user
account in the dashboard sidebar which might cause a problem with
"content_for"?
The only problem you may have is a "namespace collision" - if you are using yield :sidebar and a gem for example is also using the same name for a yield you may have unexpected results.

Rendering only authorized (Devise) user data in Rails without excess empty space

I am trying to create a todo app that will allow the user to create lists and then "todo" items under each list. However, I want each user to only be able to see his or her lists. While I've been able to partially solve it using the current_user helper, the index page shows empty space where the other users lists are hidden.
Below please find the code for the index.html.erb page inside my todo_lists views.
<% #todo_lists.each do |todo_list| %>
<div class="index_row clearfix">
<% if todo_list.user == current_user %>
<h2 class="todo_list_title"><%= link_to todo_list.title, todo_list %></h2>
<p class="todo_list_sub_title"><%= todo_list.description %></p>
<p><%= todo_list.user.first_name %></p>
<% end %>
</div>
<% end %>
<div class="links">
<%= link_to "New Todo List", new_todo_list_path %>
</div>
Here's my repo on Github, in case you need to see more of the code: https://github.com/jramoscolon/todo
Is there a way to hide these empty spaces, as well as the non-matching todo items?
Given your current view code, you are indiscriminately emitting <div class="index_row clearfix"> elements, even when the todo_list.user does not match the current_user. Simply move the whole<div> outside the current_user check, like so:
<% #todo_lists.each do |todo_list| %>
<% if todo_list.user == current_user %>
<div class="index_row clearfix">
<h2 class="todo_list_title"><%= link_to todo_list.title, todo_list %></h2>
<p class="todo_list_sub_title"><%= todo_list.description %></p>
<p><%= todo_list.user.first_name %></p>
</div>
<% end %>
<% end %>
This way, all of those empty <div> elements aren't included on the page. This should clean up all that empty space.
If your index view is user specific than the instance variable you want should be user specific as well.
Instead of #todo_lists = ToDoList.all
Use the current_user.todo_lists functionality supplied by your has_many/belongs to

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