I’m having trouble with ordering my houses. I have a houses that belong_to category (category has_many houses) and I want to order the houses on the index based on their category_id, but whatever I try it doesn’t seem to change the order. It’s a mystery to me. Maybe you could help me out?
class HousesController < ApplicationController
skip_before_action :authenticate_user!, only: [:index, :show]
before_action :set_house, only: [ :show, :edit, :update, :destroy, :inquiry ]
def index
# byebug
#houses = policy_scope(House).order(:name)
#houses = params.has_key?(:h) ? index_result(#houses) : #houses
# split_categories(#houses)
end
def index_result(houses)
# byebug
wall_thickness = params[:h].to_i
if wall_thickness == 1
houses.order(:name)
render "results_index_all"
elsif wall_thickness == 28 || 40
houses = houses.where(:wall => wall_thickness)
houses.order(:name)
render "results_index"
else
end
end
def split_categories(houses)
# #houses_1 = #houses.where(price_cents: 0...260000)
# #houses_2 = #houses.where(price_cents: 260000..1000000)
# byebug
category = Category.find_by(id: params[:category])
houses = #category.present? ? category.houses.order(price_cents: :asc) : houses
end
def show
end
def new
#house = House.new
authorize #house
end
def create
#house = House.new(house_params)
#house.user = current_user
authorize #house
if #house.save
redirect_to house_path(#house)
else
render :new
end
end
def edit
end
def update
if #house.update(house_params)
redirect_to house_path(#house)
else
render :edit
end
end
def destroy
#house.destroy
redirect_to root_path
end
private
def set_house
#house = House.friendly.find(params[:id])
authorize #house
end
def house_params
params.require(:house).permit(:sku, :name, :price_cents, :width, :length, :wall, pictures: [])
end
end
Below is the normal index where I split houses up in categories starting with category_id: 2 (normal garden houses), then 1 (gazebos) and finally 3 (garages). This is partial which is rendered app/views/houses/index.html.erb
<% if !#category %>
<%= render 'first-banner-home' %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.where(category_id: 2).each do |house| %>
<div class="col-sm-6 col-md-4">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="container catalog">
<h3><%= t('home.gazebos') %></h3>
<div class="row">
<% #houses.where(category_id: 1).each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="container catalog">
<h3><%= t('home.garages') %></h3>
<div class="row">
<% #houses.where(category_id: 3).each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% elsif params[:h].present? %>
<%= render "results_index" %>
<% else %>
<%= render "category_index" %>
<% end %>
This is the index where the houses are filtered based on their wall thickness (see in app/controllers/houses_controller.rb ). This is where I want the house to order based on their category_id, which doesn’t work at the moment.
<% content_for(:title) do %><%= t('topbar.brand') %><% end %>
<% content_for(:og_site_name) do %><%= t('topbar.brand') %><% end %>
<% content_for(:description) do %><%= t('garden_houses.meta_description') %><% end %>
<% content_for(:og_image) do %><%= cl_image_path("https://res.cloudinary.com/www-ibizagardenhouses-com/image/upload/c_scale,h_630,w_1200/v1558696079/ibi-3/image.jpg") %><% end %>
<% content_for(:og_description) do %><%= t('garden_houses.meta_description') %><% end %>
<%= render 'first-banner-results' %>
<% if #houses.count >= 4 %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6 col-md-4">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% else %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% end %>
This is exactly the same html as app/views/houses/results_index.html.erb , but where I show all the houses (params[h: 1]) in a layout that’s not the same as the home page. Same problem here as on the filtered results page.
<% content_for(:title) do %><%= t('topbar.brand') %><% end %>
<% content_for(:og_site_name) do %><%= t('topbar.brand') %><% end %>
<% content_for(:description) do %><%= t('garden_houses.meta_description') %><% end %>
<% content_for(:og_image) do %><%= cl_image_path("https://res.cloudinary.com/www-ibizagardenhouses-com/image/upload/c_scale,h_630,w_1200/v1558696079/ibi-3/image.jpg") %><% end %>
<% content_for(:og_description) do %><%= t('garden_houses.meta_description') %><% end %>
<%= render 'first-banner-all' %>
<% if #houses.count >= 4 %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6 col-md-4">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% else %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% end %>
As you can see, there's a lot of duplication of code (not very DRY) and so I'd like a little help in getting more DRY and have the houses be ordered by category_id and then by price.
I'd appreciate your help.
It's not clear to me what you tried so far, but if all you need is to sort by category_id, I think you can define a scope within your house model as follow:
scope :sort_by_category_id_asc, ->{
order(arel_table[:category_id].asc)
}
Then you can use that scope as follow: House.where(...).sort_by_category_id_asc, also you can use desc, depends on how you want to order the result.
Hope this helps! 👍
I created a method that can sort houses by its category_id. If you want to sort it by other things just change category_id to your desired thing. You can sort it ascending or descending order. Here it is:
def sort_by_category_id(houses, order)
case order_by
when "asc"
houses = houses.sort_by{ |house|
house[:category_id]
}
when "desc"
house= house.sort_by{ |house|
house[:category_id]
}.reverse!
end
house
end
Don't forget to call this method wherever you want it to be worked. Below code will sort your houses by category_id and save it in sorted_houses variable. I
sorted_houses_asc = sort_by_category_id(#houses, "asc")
sorted_houses_desc = sort_by_category_id(#houses, "desc")
Hope this helped you somehow.
My form works the way I intended it to before I filter the results in table.
The intended functionality is, allow user to select multiple objects, the selected object id's are submitted in the params hash, and accessible via params[:event_ids], when the user clicks the 'Submit' button (I've re-labeled the 'submit' button to 'swap' to clarify functionality for the user")
When I filter the results via ajax, the checkboxes and the submit button are still visible in the view, but when I click 'swap', the selected objects are not being submitted with form. I.E params[:event_ids] is not present in the params hash. I'm stumped.
Here is the code:
show.html.erb
<div class="jumbotron">
<div class="container">
<h1><%=#carpool.name%> Carpool!</h1>
<p>View carpool specific events; Send Invites and Add Events if you are the carpool manager; View a list of all members in the carpool</p>
<% if current_user == #carpool.manager %>
<p>
<a class="btn btn-primary btn-lg" href="<%=#carpool.id%>/events/new" role="button">Add Events</a>
<a class="btn btn-primary btn-lg" href="<%=#carpool.id%>/invites/new" role="button">Send Invites</a>
</p>
<% end %>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-3">
<%= render 'show_members_list' %>
</div>
<div class="col-md-9">
<%= render 'show_events_list' %>
</div>
</div>
</div>
_show_events_list.html.erb
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Drive Events</div>
<div class="panel-body">
<div class="btn-group right" role="group" aria-label="...">
<%= button_to "All Drive Events",
carpool_path(#carpool) + '?search=all',
type: "button",
remote: true,
method: :get,
class: "btn btn-default" %>
<%= button_to "I'm Driving",
carpool_path(#carpool) + '?search=my_events',
type: "button",
remote: true,
method: :get,
class: "btn btn-default"
%>
<%= button_to "I'm being Picked Up",
carpool_path(#carpool) + '?search=not_driving',
type: "button",
remote: true,
method: :get,
class: "btn btn-default"
%>
</div>
<div class="swap_button"><%= submit_tag 'Swap!', data: {confirm: "Are you sure?"}, class: "btn btn-primary btn-lg swap", id: "swap_submit" %></div>
</div>
<!-- Table -->
<table class="table">
<thead>
<tr>
<th>Who's Driving?</th>
<th>Event Name</th>
<th>Drive Event Type</th>
<th>Place</th>
<th>Game/Not Game</th>
<th>Address</th>
<th>Date</th>
<th>Swap</th>
</tr>
</thead>
<%= form_tag carpool_path(#carpool), method: :get, id: "swap_form" do %>
<tbody id="carpool_events">
<%= render 'events_list.html.erb', locals: {events: #events} %>
</tbody>
<% end %>
</table>
</div>
_events_list.html.erb
<% if #events != nil %>
<% #events.each do |event| %>
<% if event.driver_id != nil %>
<tr>
<td><%= event.driver ? event.driver.name : "swapped"%></td>
<td><%= event.name%></td>
<td><%= event.drop_off? ? "Drop Off At" : "Pick Up From" %></td>
<td><%= event.location_name%></td>
<td><%= event.is_game ? "Game" : "Not Game(event, practice)" %></td>
<td><%= event.location_address %></td>
<td><%= event.date ? event.date.strftime("%A, %d %b %Y %l:%M %p") : "Please Enter Details on TeamSnap!"%></td>
<td>
<% if current_user == event.driver %>
<%= check_box_tag "event_ids[]", event.id %>
<% end %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
show.js.erb
$("#carpool_events").html("<%= escape_javascript(render partial: 'events_list', locals: { events: #events } ) %>");
trying something like this
<%= check_box_tag "carpool[event_ids][]", event.id %>
and your console logging verify the params that will appear
I have two models for communication, Post and Reply. For some reason I can't figure out, the #reply form is unresponsive. Submit does not work, and the file upload field does not work, but only on the #reply form, the #prosect and #post forms work perfectly.
<h1><strong><%= #group.name %></strong></h1>
<p><em><%= #group.description %></em><p>
<p>Operated by: <% #owner = User.find(#group.owner_id) %><%= #owner.name %></p>
<% if current_user.group_id == nil %>
<%= form_for(#prospect) do |f| %>
<%= f.hidden_field :group_id, value: #group.id %>
<%= f.submit "Join Group", class: "btn btn-primary" %>
<% end %>
<% end %>
<% if current_user.group_id == #group.id %>
<%= form_for(#post) do |f| %>
<%= f.hidden_field :group_id, value: #group.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<div class="form-group col-xs-12">
<div class="row">
<div class="col-xs-11">
<%= f.text_area :content, class: 'form-control', placeholder: "What ails you?" %>
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-success" onclick="addpic(0);">Add a pic</button>
</div>
</div>
</div>
<div class="form-group hidden col-xs-12" id="picture0">
<%= f.file_field :image, class: 'form-control' %>
</div>
<div class="form-group col-xs-12 actions">
<%= f.submit %>
</div>
<% end %>
<% #group.posts.each do |p| %>
<div class="post">
<div class="post-meta">
<%= p.user.name %> <em><%= p.created_at.strftime('%a, %b %e, %Y %r') %></em>
</div>
<%= p.content %>
<% if p.image %>
<img src="data:image/png;base64,<%= p.image %>" class="img-responsive"/>
<% end %>
<% p.replies.each do |r| %>
<%= r.user.name %><br/><%= r.content %>
<% if r.image %>
<img src="data:image/png;base64,<%= r.image %>" class="img-responsive"/>
<% end %>
<% end %>
<a class="reply">Reply</a>
<div class="reply hidden">
<%= form_for(#reply) do |ff| %>
<%= ff.hidden_field :post_id, value: p.id %>
<%= ff.hidden_field :user_id, value: current_user.id %>
<div class="form-group col-xs-12">
<div class="row">
<div class="col-xs-11">
<%= ff.text_area :content, class: 'form-control', placeholder: "Write a reply..." %>
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-success" onclick="addpic(<%= p.id %>);">Add a pic</button>
</div>
</div>
</div>
<div class="form-group hidden col-xs-12" id="picture<%= p.id %>">
<%= ff.file_field :image, class: 'form-control' %>
</div>
<div class="form-group col-xs-12 actions">
<%= ff.submit %>
</div>
<% end %>
</div>
</div>
<% end %>
<% end %>
<script>
var addpic = function(id) {
var el = '#picture' + id;
$(el).removeClass('hidden');
}
$('.reply').on('click', function(e){
e.preventDefault();
$(this).next().removeClass('hidden');
});
</script>
Figured out the issue, JS was preventing the default for all clicks inside a .reply div. Had reply used in the wrapper for the reply form, so it was preventing the default. Got it working now by changing the class of the reply link to 'addreply' and the js listener to 'addreply' as well.
I have the code below and I want to create an tag between the div with the class 'box'.
I cant just use the link_to method because I want this link to encompass all the html code from the to its respective ending . So anyone who clicks within that box gets transported to the equivalent of: <%= link_to( 'go', { action: :edit, id: course.id }) %>. I tried finding this else where but failed.
<% #courses.in_groups_of(3, false) do |group| %> <!--Takes groups of three courses -->
<div class="row">
<% group.each do |course| %>
<div class="col-xs-12 col-sm-6 col-lg-4">
<div class="box">
<div class="icon">
<div class="image"><span class="glyphicon glyphicon-list-alt btn-lg white"></span></div>
<div class="info">
<h3 class="title"><%= course.name %> | GPA: <%= course.gpa.to_f %></h3>
<p>
<%= course.description %>
</p>
<div class="more">
<a href="#" title="Title Link"><i class="fa fa-plus"></i> Details
</a>
<%= link_to( 'go', { action: :edit, id: course.id }) %>
</div>
</div>
</div>
<div class="space"></div>
</div>
</div>
<% end %>
</div>
<% end %>
<%= link_to({ action: :edit, id: course.id }) do %>
<div class="box">
<div class="icon">
<div class="image"><span class="glyphicon glyphicon-list-alt btn-lg white"></span></div>
<div class="info">
<h3 class="title"><%= course.name %> | GPA: <%= course.gpa.to_f %></h3>
<p>
<%= course.description %>
</p>
<div class="more">
<i class="fa fa-plus"></i> Details
</div>
</div>
</div>
<% end %>
I am not sure I understand your question, but I think you are asking to enclose your html code into a link_to tag. So try this:
<%= link_to path_to_land_on do %>
<div class='box'>
// other code
</div>
<% end %>
Replace path_to_land_on with { action: :edit, id: 2 } or path
I'm having a problem with my advanced search.
Essentially, its an advanced search for bands (name, style, bandpicture by checkboxes (checked: have a bandpicture))
Here is the code.
result.html.erb
<table >
<colgroup>
<col width="250" />
</colgroup>
<tr>
<td>
<label for="name">Filter</label></br>
<%= form_tag band_path do %>
<label for="Style">Style</label></br>
<%= select_tag :style_id, options_from_collection_for_select(Style.all, :id, :name, params[:style_id]), include_blank: true, class: "form-control" %>
<br>
</br>
<%= check_box_tag 'options[]', "picture" %>
<%= button_to '#', class: 'btn btn-default' do %>
<%= t(:find) %>
<% end %>
<% end %>
</td>
<td>
<div>
<% #bands.each do |band|%>
<div class="top-bar">
<div class="center">
<div class="info">
<div class="name"><%=band.id %></div>
<div> <%= band.zip %>, <%= band.city %> </div>
</div>
<div class="desc">
<table>
<tr>
<td>Styles</td>
<td>
<% band.styles.each do |s| %>
<%= s.style.name %>
<% end %>
</td>
</tr>
</table>
</div>
<% end %>
</td>
</tr>
</table>
models band.rb
def self.search1(style_id)
Profile.joins("...").where("style_id = ?", style_id)
end
controller.
def searchresult
if params[:style_id].present?
#bands = Band.search1 params[:style_id]
elsif params[:options]
Band.where(:options => #filtered_options)
else
#bands = Band.all
end
end
The searchresult don't show the result of the checkboxes and I have this errors:
undefined method `search1' for #<Class:0x00000008eb5548>