Rails 5 Navigational Menu from deep nested routes - ruby-on-rails

I need to create a dropdown sidebar navigational menu from my Rails 5 nested routes. I have 4 models - locations, categories, subcategories and products. We currently have 4 locations, so I created a query in my application_controller to default the path to our corporate location, San Diego.
From there, I created a category query based on the location query. All is good, I can iterate and print the results to the view, with the category as the title of the dropdown. I need to show the sub-categories in the category dropdown they belong to but I keep getting an undefined error.
I know the nested routes that I have are not ideal for most situations, but this site needs absolute defined urls for search engine ranking...just so you know before you comment on them.
application_controller.rb
class ApplicationController < ActionController::Base
...
before_action :load_vendors
def load_vendors
#location = Location.find_by_name('San Diego')
#category = #location.categories
#subcategory = #category.subcategories
end
...
routes.rb
resources :locations do
resources :categories, path: '' do
resources :subcategories, path: '' do
resources :products, path: ''
end
end
end
_sidebar.html.rb
<div id="ss_menu">
<% #category.each do |c| %>
<div class="ss_button"><%= c.name %></div>
<div class="ss_content">
<ul>
<% #subcategory.each do |s| %>
<li>
<a href="">
<%= s.name %>
</a>
</li>
<% end %>
</ul>
</div>
<% end %>
</div>

First of all, you forgot to add erb extension _sidebar.html.erb.
Moreover, this is what the view should look like:
<div id="ss_menu">
<% #categories.each do |category| %>
<div class="ss_button"><%= category.name %></div>
<div class="ss_content">
<ul>
<% category.subcategories.each do |subcategory| %>
<li>
<%= link_to subcategory.name, ... %>
</li>
<% end %>
</ul>
</div>
<% end %>
</div>
What kind association type do you used for categories?

Related

Strange Things - Ruby on Rails 5

Hey guys I'm trying to catch all my categories descriptions inside my Category model and show them at my shop index page. So far everything working fine. All categories came perfectly at screen but just below then rails shows all categories as an array.
This is my Category controller
class Site::HomeController < ApplicationController
def index
#categories = Category.all
end
end
This is my index page
`
<div class="row">
<div class="col-lg-3">
<h1 class="my-4">Shop Name</h1>
<div class="list-group">
<%= #categories.each do |cat| %>
<%= cat.description %>
<% end %>
</div>
</div>`
and below you can check the issue
I appreciate for some help.
regards
Try this:
<% #categories.each do |cat| %> #remove "="
<%= cat.description %>
<% end %>

Ruby on rails Merge two routes

So i have the controller named collection and the model name products.
The collection page is showing all the products.
Here is the code that show's the products
<% #products.each do |x| %>
<div class="col-lg-3">
<div class="product-container animated fadeIn">
<div class="product-image-holder">
<%= image_tag x.image1.url(:fhd) %>
</div>
<div class="product-title-holder">
<span class="product-title"><%= x.title %></span>
</div>
</div>
</div>
<% end %>
Now i want to wrap each product in it's own link ( link to single product )
i managed to do that but the link will be www.localhost.com/product/1 instead of this i want to be www.localhost.com/collection/product/1
Any help ? :)
This are the routes
get 'collection', to:'collection#index'
resources :product
Use a scope
scope '/collection' do
resources :products
end
More info here: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing

Get random child record without accessing individual parent record - Rails 4

I am creating a quiz like website.
I have categories, questions and choices as tables.
What i want is, where i list my categories, when i click on category, i want it to take me to the categories/1/questions/<random question> path.
the relationships are set up
here is what i have so far.
index.erb.html (of categories)
<ul class="categories-list">
<% #categories.each do |category| %>
<% if category.header %>
<% #count = #count + 1 %>
<li class="panel header" id="cat<%= #count %>">
<%= category.title %>
<small>781 of 781 questions remaining</small>
</li>
<% else %>
<li class="panel sub hidden subcat<%= #count %>" >
<%= link_to category.title, category_question_path(category,category.questions.limit(1).order("RAND()")) %>
<small>781 of 781 questions remaining</small>
</li>
<% end %>
<% end %>
</ul>
categories-controller.rb
def index
#count = 0
#categories = Category.order(:tag)
end
The most generic way to do this (independent of database vendor):
category.questions.offset(rand(category.questions.count)).first
Vendor specific queries are also possible:
category.questions.order("RANDOM()").first # postgres
category.questions.order("RAND()").first # mysql
Define new action /random_question:
def random_question
category = Category.find params[:category_id]
question = category.questions.offset(rand(category.questions.count)).first
redirect_to question_path(question)
end

Rails link_to an .each join

I have this code which associates one table to another. Using Set it collects all data and only shows it once if there are other similar values.
genre_names = Set.new
<% #pm_relationships = PmRelationship.where(:people_id => #person.id) %>
<% #pm_relationships.each do |pm_relationship| %>
<% #movie=Movie.find(pm_relationship.movie_id) %>
<% #mg_relationships = MgRelationship.where(:movie_id => #movie.id) %>
<% #mg_relationships.each do |mg_relationship| %>
<% #genre=Genre.find(mg_relationship.genre_id) %>
<% genre_names.add(#genre.name) %>
<% end %>
<% end%>
# actual view code
<ul class="basic-info-genres">
<%= "<li>#{genre_names.to_a.join('</li><li>')}</li>".html_safe %>
</ul>
My problem here is how a link_to would work in the print code provided
<%= "<a><li><button><span>#{genre_names.to_a.join('</span></button></li></a><a><li><‌​‌​button><span>')}</span></button></li></a>".html_safe %>
How to make the above print to have this link to /genres/<%=#genre.id%>?
I've tried
<%= "<a href='/genres/#{#genre.id}'><li><button><span>#{genre_names.to_a.join('</span></‌​‌​button></li></a><a><li><button><span>')}</span></button></li></a>".html_safe %>
but this only links to the first genre shown
Any ideas?
Thanks
Add to genres the whole #genres, not only the #genre-name, then you can use the each-loop in the view code.
For the Controller (you should have your programmic logic there):
#genres = Set.new
#pm_relationships = PmRelationship.where(:people_id => #person.id)
#pm_relationships.each do |pm_relationship|
movie=Movie.find(pm_relationship.movie_id)
#mg_relationships = MgRelationship.where(:movie_id => movie.id)
#mg_relationships.each do |mg_relationship| %>
genre=Genre.find(mg_relationship.genre_id) %>
#genres.add(genre) %>
end
end
For the view:
<ul class="basic-info-genres">
<% #genres.each do |genre| %>
<li><%= link_to genre.genre_name, "#{root_url}genres/#{genre.id}" %></li>
<% end %>
</ul>
If I understand correctly, you want to link all genres that are associated with a movie.
To do this, in your controller, load the genres for a user's movies. With the correct association setup, this is as easy as #person.genres. So let's do that.
class Person < ActiveRecord::Base
has_many :pm_relationships
has_many :movies, through: :pm_relationships
has_many :genres, through: :movies
end
class PmRelationship < ActiveRecord::Base
belongs_to :person
belongs_to :movie
end
class Movie < ActiveRecord::Base
has_many :mg_relationships
has_many :genres, through: :mg_relationships
end
With that setup, in your controller, just setup an instance variable to list all genres for #person
#genres = #person.genres
Then in your view, use the block form of link_to so it's easier to code your html
<ul class="basic-info-genres">
<% #genres.each do |genre| %>
<%= link_to genre do %>
<li>
<button>
<span><%= genre.name %>‌</span>
</button>
</li>
<% end %>
<% end %>
</ul>
Basically, you can't have any direct child element instead of li within ul. You will need to have <a> within li, however, we can apply css to <a> so that it looks like whole 'li' have the clickable link.
From your actual code, update the snippet.
<ul class="basic-info-genres">
<% genre_names.each do |genre_name| %>
<li>
<%= link_to genre_name, genre_path(#genre), :class => 'clickable-li' %>
</li>
<% end %>
</ul>
You need to set your <a> to display: block;
# css file
.clickable-li {
display: block;
}

Need to group shows by day in a rails Application

I am trying to get shows on a certain day to show up just for that day and I would like to be able to see what shows are going on in the next couple of days as well.
The View:
<% t = Time.new %>
<h2 class="center" style="color:#2A2C2B"><u><%= t.strftime("%A, %B %e") %></u></h2>
<% #clubs.each do |club| %>
<!-- # <% club.shows.future.present? %> -->
<h1 class="club"><%= link_to club.name, club.website %> </h1>
<% club.shows.future.each do |show| %>
<h3 class="center"><%= show.pretty_start_time %></h3>
<% show.comedians.each do |comedian| %>
<div>
<ol>
<h4 class="comedian"><%= link_to simple_format(comedian.name),comedian_path(comedian) %></h4>
<p class="bio"><u><%= comedian.bio %></u></p>
</ol>
</div>
<% end %>
<% end %>
<%- end -%>
The Comedy Hub Controller:
class ComedyHubsController < ApplicationController
def show
#clubs = ComedyClub.all
end
end
This might work:
<% shows.goup_by{|show| show.date}.each do |dategroup| %>
<# do something to indicated the group up here? %>
<%= dategroup.each do |show| %>
<li> <%# put details here %> </li>
<% end %>
<% end %>
Assuming, there is a DateTime column on Show called start and the ComedyClub model has a a has_many :shows and the Show model has the belongs_to :comedy_club association defined
In your ComedayHubsController#show method, do the following query
#clubs = ComedyClub.join(:shows).where("shows.start >=?", DateTime.now).order("shows.start ASC")
Now only clubs with shows in the future will be sent to the view and already ordered by start.

Resources