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.
Related
I'm using the following code to display posts to my users.
_feed.html.erb partial:
<% #posts_by_month.each do |monthname, posts| %>
<%= monthname %>
<ul>
<% posts.each do |post| %>
<li><%= post.created_at %></li>
<% end %>
</ul>
<% end %>
Controller:
def home
if logged_in?
#post = current_user.posts.build
#posts_by_month = current_user.feed.group_by { |post| post.created_at.strftime("%B") }
This renders my posts as follows:
Post 1
Post 2
Post 3
Post 4
I want to change it so that the posts are displayed like:
Post 1 Post 2 Post 3
Post 4 etc etc
etc
I've tried several approaches to this, including the in_groups_of(3) method however the way it is currently setup means nothing works. I feel like there is an obvious solution I'm missing - can anyone help?
[Edit to expand on the in_groups_of(3) error]
If I change line 4 in the _feed partial to:
<% posts.in_groups_of(3, false).each do |post| %>
It gives the error: undefined method `created_at' for #< Array:0xbb8f258 >
The #in_groups_of method returns an Array of Arrays each containing 3 Post objects.
So you now also need to iterate over the returned array that contains your three Posts, something like:
<% posts.in_groups_of(3, false).each do |post_group| %>
<% post_group.each do |post| %>
<li><%= post.created_at %></li>
<% end %>
<% end %>
You can use facets gem. This provides and each_by method. You can use each_by to create groups and iterate further on these groups.
Here is code snippet on how to use each_by
<div class = "small-9 columns vertical-border-left">
<%- #client.contact_details.each_by(3) do |contact_details| %>
<div class="row">
<%- contact_details.each do |contact| %>
<div class="small-3 columns small">
<div> <%= contact.contact_detail_type %> contact </div>
<div> <%= contact.contact_email %> </div>
<div> <%= contact.contact_phone %> </div>
</div>
<% end %>
</div>
<% end %>
</div>
So in my tutors_controller.rb this is my index action
def index
#tutor = Tutor.all
#tutor = #tutor.fees_search(params[:fees_search]) if params[:fees_search].present?
end
and in my index.html.erb this is the view
<div class='container'>
<%= form_tag(tutors_path, method: :get) do %>
<%= label_tag 'fees_search', 'Max Fees' %>
<%= select_tag 'fees_search', options_for_select((10..50).step(10)) %>
<%= submit_tag 'Filter' %>
<% end %>
<% #tutor.each do |tutor| %>
<% unless tutor.admin? %>
<div class='row' id='tutor-listing'>
<div class='col-xs-4'>
<%= image_tag(tutor.profile.avatar.url, :class => "img-rounded" ) if tutor.profile.avatar? %>
</div>
<div class='col-xs-8'>
<h3><%= link_to tutor.full_name, tutor_path(tutor) %></h3>
<% unless tutor.subjects.nil? %>
<% tutor.subjects.each do |subs| %>
<span class='badge'id='tutor-listing-badge'>
<%= link_to subs.name, subject_path(subs) %>
</span>
<% end %>
<% end %>
<% unless current_tutor %>
<%= button_to "Shortlist Tutor", add_to_cart_path(tutor.id), :method => :post %>
<% end %>
</div>
</div>
<% end %>
<% end %>
</div>
So i understand that when the index view first renders, #tutor would simply be Tutor.all so it renders each individual tutor perfectly.
After trying to filter it though, i start receiving errors. The exact error is NoMethodError in Tutors#indexand the highlighted line is <% unless tutor.admin? %>
profile.rb model
class Profile < ActiveRecord::Base
belongs_to :tutor
scope :fees_to, -> (fees_to) { where("fees_to <= ?", "#{fees_to}") }
end
tutor.rb model
class Tutor < ActiveRecord::Base
has_one :profile, dependent: :destroy
def self.fees_search(n)
#profile = Profile.fees_to(n)
if #profile.empty?
return Tutor.none
else
#profile.each do |y|
y.tutor
end
end
end
end
I get that now my #tutor instance variable has obviously changed. But how do i go about resolving this problem? Should i be rendering a partial instead? Obviously my index action in my controller could be "better" also but i'm quite confused now as to what i should be doing.
Would appreciate any advice! Thank you!
#profile.each do |y|
y.tutor
end
Seems to be a problem. All the other outcomes are a Tutor.something scope, whereas this will return the last tutor only. Change each to map to get an array of Tutors instead.
In my rails category show controller for categories I have it setup like this
def show
#categories = Category.find_by(params[:name])
end
But when I visit this controller it returns all records of products found in the category instead of single category.
Here is the code in my view controller for category
<div class="grid">
<% #categories.products.each do |product| %>
<%= link_to product_path(id: product.slug, category_name: product.category.name), class: "card" do %>
<div class="product-image">
<%= image_tag product.productpic.url if product.productpic? %>
</div>
<div class="product-text">
<h2 class="product-title"> <%= product.name %></h2>
<h3 class="product-price">£<%= product.price %></h3>
</div>
<% end %>
<% end %>
</div>
What am i doing wrong here?
First of all, for security purposes, you should never trust the params hash to retrieve records. Rails will "make the data safe" if you use a hash as your arguments. Use this code below:
def show
#category = Category.find_by(name: params[:name])
end
Second, usually on a show page, you only want to retrieve one record and therefore the variable should be named as singular. I corrected that above.
Third, it helps if you use proper indenting when posting examples. It makes it easier for us to help you.
Fourth, the line below (I changed #categories to #category) is basically saying: "Now that I have this single category, find all the products associated with it in the products table and put them into the |product| variable for iteration"
<% #category.products.each do |product| %>
I'm not sure what you want to do with the category, but if you keep this line of code, it will always show you all the products. Maybe you only want to show the most recent 3, in which case you could do something like this:
In your controller:
def show
#category = Category.find_by(name: params[:name])
#recent_products = #category.products.order(created_at: :desc).limit(3)
end
In your view:
<div class="grid">
<% #recent_products.each do |product| %>
<%= link_to product_path(id: product.slug, category_name: product.category.name), class: "card" do %>
<div class="product-image">
<%= image_tag product.productpic.url if product.productpic? %>
</div>
<div class="product-text">
<h2 class="product-title"> <%= product.name %></h2>
<h3 class="product-price">£<%= product.price %></h3>
</div>
<% end %>
<% end %>
</div>
You can do this way
in your controller you can write this code
def show
#category = Category.find_by_name(params[:name])
end
and in your view it will work
<div class="grid">
<% #category.products.each do |product|%>
// place your code what you want to display
<% end %>
</div>
I hope it would help you and still if you have any concern please let me know.
I've in my app, posts as ideas, and these ideas belongs to an activity and a status.
And I want to sort them by activity for one status so I did in my controller
#idees_en_place = Idee.where(statut_id= "2")
#activites = Activite.all
And in my view :
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% #idees_en_place.where(activite_id = activite.id).limit(3).each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
But that doesn't work, in each part of an activity the ideas are not sorted.
I think it's a little mistake but I don't know how to resolve this
#idees_en_place = Idee.where(statut_id= "2")
There are two problems with this code.
First, id is a Integer type (unless you've defined it as String).
Second, its a key value you pass to where clause, and you pass these either as
:status_id => 2 # old hashrocket syntax
or
status_id: 2 # new syntax
The same goes with this part
#idees_en_place.where(activite_id = activite.id)
it should be
#idees_en_place.where(activite_id: activite.id)
In Controller
#idees_en_place = Idee.where(statut_id: 2)
#activites = Activite.all
In View
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% #idees_en_place.where(activite_id: activite.id).limit(3).each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
I just wanna point out that you will run into an N+1 queries issue, to avoid this you should preload every thing, instead of doing queries in the views.
The controller:
#change if the association name is different
#activites = Activite.includes(:idees)
The view
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% activitie.idees[0..2].each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
Notes:
I've used the [0..2] format because I wanted to avoid ActiveRecord from doing a new query, another method would be limiting the query using something like this
#activites = Activite.includes(:idees).merge(Idee.limit(3))
Then you won't need to use any limitation in the views, but I haven't tested this, don't have access on a rails machine right now.
I think that the following code will help you:
Since your Idee belong to activity and status that's why you have activity_id and status_id in your Idee table.
you may find out all the idee for a status by using:
Idee.where(:status_id => 2)
and you can sort Idee in Asc or desc order by using order
idees = Idee.join(:activity).where(:status_id => 2).order(:activity_id => :asc)
idees = Idee.join(:activity).where(:status_id => 2).order(:activity_id => :desc)
<% activity_id = -1%>
<#idees.each do |idee| %>
<div class="idee en-place col-lg-5" style="background:#<%= idee.activite.color%>">
<h2><%= idee.activity.name %></h2>
<p>
<% if activity_id != idee.activity_id %>
<% activity_id = idee.activity.id %>
<% counter = 0 %>
<% end %>
<% if counter < 3 %>
<% counter = counter + 1%>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
This code here groups a Users friends by highschool name.
<% #user.friends.group_by(&:highschool_name).map do |hsname, friends| %>
<% next if hsname.blank? %>
<div class="contentbox">
<div class="box-header">
<h3><%= hsname %></h3>
</div>
<ul class="friends-list">
<% friends.map do |friend| %>
<li><%= image_tag(friend.image) %>
<% end %>
</ul>
</div>
<% end %>
But it groups with out any order, I would like to order by highste value. Showing the highest group first and down. Any ideas?
group_by gives you a hash in return. You can sort on count of values before iterating:
groups = #user.friends.group_by(&:highschool_name)
sorted_groups = groups.sort_by{|key, values| values.count}.reverse
sorted_groups.each do |hsname, friends|
# do your thing here
end
Did you try?
#user.friends.group(:highschool_name).order("highschool_name DESC")