RoR View: List results grouped under categories - ruby-on-rails

I am trying to group a set of products (obtained typing a query) based on taxonomy(on of the attributes of a product)
My desired output is
Taxonomy 1
prod1 prod2 prod3 prod4
prod 5 ...
Taxonomy 2
pod6 prod7
Taxonomy 3
prod8 prod9..
I am using the following code in the view:
<% taxonomies.each do |taxonomy|%> #"taxomonies" is a set of unique taxonomies for retrieved products
<h1><%= taxonomy%></h1>
<ul>
<% collection.each_with_index do |product,i| %> #"collection" is the list of products retrieved
<li>
<%#ptaxon = product.get_taxonomy%>
<%if #ptaxon == taxonomy%>
<%code for listing product%>
<%end%>
</li>
<%end%>
</ul>
<%end%>
This groups the products based on taxonomies but the format is not what I desire. Could someone please point out my mistake.
EDIT: also tried using < br > , but doesn't help!
This is the output I'm getting. I want the taxonomies earrings, bracelets and necklaces to start from a new line.
Thanks

If you have your associations setup correctly, you can do it like this:
<% taxonomies.each do |taxonomy| %>
<%= taxonomy.name %>
<% taxonomy.products.each do |product| %>
<%= product.name %>
<% end %>
<% end %>
Models should be something like:
class Taxonomy
has_many :products
end
class Product
belongs_to :taxonomy
end

Related

How to loop through a self referential model in Ruby on Rails

I'm new to ruby on rails and I'm building a wiki app where the navigation is to be sorted by categories. Each article, or page, can belong to a category, but a category can also be a sub-category of another category. An administrator will be able to create new categories or sub-categories calling for a dynamic approach to generating a list of categories for the menu. I'm trying to figure out how to display a list of all parent categories and all of their children and grandchildren categories where the menu would look something like this:
1. Parent1
1.a Child1
1.b Child2
2. Parent2
2.a Child1
2.a.1 Grandchild1
I currently have some nested loops in my view which kind of work, but it's not dynamic since it will only show the first two generations, and I would have to repeat the code to show more.
Model:
class Category < ApplicationRecord
has_many :sub_categories, class_name: "Category", foreign_key: "category_id"
belongs_to :category, class_name: "Category", optional: true
end
Controller:
class CategoriesController < ApplicationController
def index
#sorted_categories = Category.order(:sort_number).where("category_id IS NULL")
#sub_categories = Category.order(:sort_number).where("category_id IS NOT NULL")
end
end
View:
<% if #categories.nil? %>
<h3>There are currently no categories.</h3>
<% else %>
<ul>
<% #sorted_categories.each do |c| %>
<li><%= c.name %><%= link_to 'Move Up', categories_move_up_path(c) %> Sort:<%= c.sort_number %></li>
<% #sub_categories.each do |s| %>
<% if s.category_id == c.id %>
<ul>
<li>
<%= s.name %><%= link_to 'Move Up', categories_move_up_path(s) %> Sort:<%= s.sort_number %>
</li>
</ul>
<% end %>
<% end %>
<% end %>
</ul>
<% end %>
Any advice would be greatly appreciated, thanks!
Have a look at the acts_as_list gem, it does exactly what you want.
It will define a parent_id column, and each object will be a child of a parent, so that you can create infinite tree of categories ans sub-categories.
It also provides the methods to move objects up and down.

How tom properly display many table records in views

Here have three tables with association and relationship as follows
Categor table is the main table
Product table belongs to categor table where its product_id references categor(id)
Sale table belongs to Product table where its sale_id references product(id)
Here am am trying to get records based on their refrences where:
just consider this three tables as Categor as the main table, product as sub table and sales as sub table under product
1.) categor table will loop and display all the records in it.
2.) product table should loop and display its record based on categor_id where it matches id of the categor table.
3) sale table should loop and display its record based on product_id where it matches id of the product.
just consider this three tables as Post, comment and reply
def index
##categors = Categor.where(:id => '1')
#categors = Categor.all
#prods = Product.where(:categor_id => '1')
#sals = Sale.where(:product_id => '1')
end
At this point, I can successfully display all the records but can not get it be aligned properly.
Categor is the main table.
Products info should be under Categor.
sales info should be under products.
Just view it as post, comment and reply respectively.
<p id="notice"><%= notice %></p>
<div>
<% #categors.each do |categor| %>
Categorid: <%= categor.id %>
Category Name: <%= categor.cat_name %>
Ctaegory Label<%= categor.car_label %>
</div>
<% end %><br>
<% #prods.each do |pr| %>
Product id: <%= pr.id %>
Product Name: <%= pr.prod_name %>
<% end %>
<br>
<% #sals.each do |s| %>
sales id: <%= s.id %>
sales Name: <%= s.sales_name %>
<% end %>
<br>
<br>
I'm not sure I understand what you are trying to accomplish here, but I'm going to assume you are trying to display all categories, and all products in each category and all sales for each product.
There are several different ways that you could structure this, like for example tree views or nested tables, etc, and you should take in consideration how useable the page will be once you have a lot of categories/products/sales, but for the sake of simplicity let's structure them as nested lists:
<ul>
<% #categors.each do |categor| %>
<li><%= categor.cat_name %>
<ul>
<% categor.products.each do |pr| %>
<li><%= pr.prod_name %>
<ul>
<% pr.sales.each do |s| %>
<li><%= s.sales_name %></li>
<% end %>
</ul>
</li>
<% end %>
</ul>
</li>
<% end %>
</ul>
Now you didn't show us how your models are setup so i don't know if the relationships between them are properly set but I'm assuming yes.

Rails 5 order(:name) of has many association

I have two models, product and variation Product has_many variations and variation belongs_to product. I am displaying the variations of the products in my template but can't seem to get order(:name) to work with the variation association--the controller code below wants to order the product name.
products_controller.rb
...
#products = Product.order(:name)
...
product.html.erb
...
<% #products.each do |product| %>
<div class="grid-filter">
<% product.variations.each do |v| %>
<span class="copy">
<%= v.name %>
</span>
<% end %>
</div>
<% end %>
...
If you want to sort Product based on Variations name, You might try adding order on the associations itself in the product model as following :
class Product
has_many :variations, -> {order 'name'}
end
You can use order in the view as 'variations' is association too
...
<% #products.each do |product| %>
<div class="grid-filter">
<% product.variations.order(:name).each do |v| %>
<span class="copy">
<%= v.name %>
</span>
<% end %>
</div>
<% end %>
...
You can order it in the controller:
...
#products = Product.order(:name)
.includes(:variants)
.order('variants.name')
...

Ruby on Rails: Grouping search results by category

I am working on a RoR WebApp. I'm trying to group results on the search page based on their taxonomy. What I want to do is to show a header for a category and list all results under that category. Something like:
CAT 1
products
CAT2
products
CAT3
.
.
I am trying using the following code:
<% if products.any? %> #products is the list of search results
<%= render :partial=> 'product_listing_feature', :locals => {:scope => scope, :scope_type => scope_type} %>
<div id="ql_product"></div>
<div class="product_rows">
<%taxons.each do |taxon|%> # taxons contains the list of unique categories in products
<div class = "product_row">
<h1><%=taxon%></h1>
<% taxonProducts = Array.new %>
<% products.each do |product| %>
<%#ptaxon = product.get_taxonomy%>
<%if #ptaxon == taxon%>
<% taxonProducts.push(product) %>
<% end %>
<% end %>
<div class ="featured_product_list">
<ul class = "featured_products">
<div class = "page">
<%= render :partial=> 'product_listing', :locals=>{:collection=> taxonProducts} %>
</div>
</ul>
</div>
</div>
<% end %>
</div>
<% end %>
Surprisingly it starts the 2nd category from a new row, but the following categories appeared jumbled up, something like
CAT1
products
CAT2
products CAT3
products
picture would give a better idea.
I am really surprised why it works only for one iteration. Could someone please help me fix this.
Thanks a lot
Way, way too much logic for a view. Just use group_by in your controller, which will give you a mapping of names to arrays of products:
products = Product.includes(:taxon).group_by { |p| p.taxon.name }

Associations not working in html.erb

<ol class="noDots">
<% # #screening.cinema.each do |screening| %>
<li>
<h3><%= screening.cinema.name %></h3>
</li>
<% #end %>
</ol>
Hi everyone,
There is an association between cinema and film through screening. Film model is separate and cinema is separate. Screening combines them together. In the cinema model, everything seems to work properly <%= screening.film.title %> works perfectly and displaying them in a loop works.
I want to create a dropdown of cinema.name with the link and it takes you there. The association has to exists as some movies in different cinemas.
Is that possible as the code above doesnt work for me.
Thanks in advance
<h3><%= screening.cinema.name %></h3>
This line should read...
<h3><%= screening.name %></h3>
And you could have this dropdown box in a form with a Submit button next to it to take you to that page...
Sounds like you are getting a lot "nil object" errors. Double check your controller to see what variables you are defining there that can be accessed in the views.
Eg, if you are setting #film, then you can traverse the associations with something like:
<% #film.screenings.each do |screening| %>
<li>
<h3><%= screening.cinema.name %></h3>
</li>
<% end %>
You should be able to alphabetize by cinema name as well, if you eager-load them when you grab the list of screenings:
<% #film.screenings.includes(:cinema).order("cinema.name ASC").each do |screening| %>
<li>
<h3><%= screening.cinema.name %></h3>
</li>
<% end %>
Hope that helps!
From what I see screen has_many :cinemas( not cinema has_many :screenings)
so
<% #screening.cinema.each do |cinema| %>
<li>
<h3><%= cinema.name %></h3>
</li>
<% end %>
please show the screening model and the cinema mode, but based on the gist..
Assuming
class Screening
belongs_to :film
belongs_to :cinema.
.....
end
class Film
has_many :screenings
has_many :cinemas, :through => :screenings
end
class Cinema
has_many :screenings,
has_many :films, :through => screenings
end
I think what you want is something along the lines of the following.
<ol class="noDots">
<% # #screenings.each do |screening| %>
<li>
<h3><%= screening.cinema.name %></h3>
</li>
<% #end %>
</ol>
Assuming that you set #screenings to subset of screenings you want in the controller..
This should work as it worked on your single screening in the comments.
In the controller
#screening = Screening.find(some_id)
In the view
<% #screening.cinema.each do |s| %>
<li>
<h3><%= s.cinema.name %></h3>
</li>
<% end %>

Resources