I am new in RoR.
The problem is, I created fully functional product categorization with Ancesrty. But now I want to be able to retrieve products that is under these subcategories.
This is my categories show controller
#category = Category.find(params[:id])
Here is categories#show view.
<b>Name of the category:</b>
<%= #category.name %>
<div class="product"
</div>
</p>
<% unless #category.children.empty? %>
<ul id="sub-menu">
<% #category.children.each do |sub1| %>
<%= link_to (sub1.name), sub1 %>
<%end%>
<%end%>
It all works fine. but now I want to add in view categories/show function that shows all products that is under that category.
I added such code.
In category/show controller
#cat_id = #category.id
#product = Product.where("category_id = ?",#cat_id)
In the categories show view I added
<td><%= #product.name %></td>
Then clicking on some subcategory where should appear few products, there just shows up Product
To check if the code is right I put in the console. There it works fine and retrieve products related to this category.
I dont understand why then code not working in webserver when I launch application ?
Could it be because of some erorr in Associations ?
Thanks !
in your controller, a more readable way is to use the plural form to indicate that you are expecting more than 1 object
#products = Product.where("category_id = ?", #cat_id)
Then in the view, just loop through these products
<% #products.each do |product| %>
<%= product.name %>
<% end %>
#product = Product.where("category_id = ?",#cat_id)
will return an array if there are any products. So you will need to loop through the array.
<% #product.each do |product| %>
<%= product.name %>
<% end %>
I accept both of the answers, But I want to suggest to use Active Record Association for this type of problems. This makes your solution easier.
If you want to fetch only one product, you can use the find_by_ helper method of the model:
#product = Product.find_by_category_id(#cat_id)
With this it will fetch the first matching product which has category_id equal to #cat_id.
If you want to fetch all the products which belong to a category, you need to fetch all the products as others suggested:
#products = Product.where(:category_id => #cat_id)
And then in the view:
<% #products.each do |product| %>
<%= product.name %>
<% end -%>
Related
I have a post view where I want to display related posts but what I have now includes the current post as well.
How would I go about removing the current item from the search?
I don't know how to use where.not() or != in this situation or if they're even the best thing to use.
This is what I have in my post show view:
<% #related[#post.blog_category_id]&.each do |rel| %>
<a href="/posts/<%= rel.friendly_id %>" class="img-cont">
<%= image_tag("Index/#{rel.thumbnail_link}", :alt => "#{rel.title}", class: "soundtrack-img top-drop") %>
<div class="img-mdl wellington"><h3 class="img-txt basic"><%= rel.title %></h3></div>
</a>
<% end %>
And in my posts_controller show method:
#related = Post.friendly.all.group_by(&:blog_category_id)
#related already includes all posts, you need to remove the current post from the list or skip it in the iteration:
Exclude the current one before iterating
<% #related[#post.blog_category_id].reject { |post| post == #post }&.each do |rel| %>
or just skip the iteration if the current one is the post in question:
<% #related[#post.blog_category_id]&.each do |rel| %>
<% next if rel == #post %>
Try using .offset(1). Something like:
#related = Post.friendly.all.group_by(&:blog_category_id).offset(1)
or
#related = Post.friendly.all.group_by(&:blog_category_id).order("created_at desc").offset(1)
I need a little advice about the join and includes methods.
I display a list of groups in the index view. Each has a modal associated, and, in this modal, I would like to display the requests associated to this group. Normally, I'd use #requests = group.requests, but would like to use join for sending just one request to my database.
Since I'm in the index view, I don't have a #group in my action.
controller:
def index
#groups = current_user.groups
end
view (index):
<% #groups.each do |g| %>
<MODAL>
<% #requests = g.requests %>
<% #requests.each do |r| %>
<%= r.date %>
<% end %>
</MODAL>
<% end %>
I guess I can also use join and include for #groups, but there is already one SQL request, so I'm good with it.
In your controller, add includes like this to preload requests and avoid n+1 queries.
def index
#groups = current_user.groups.includes(:requests)
end
View is fine, but you can also write as:-
<% #groups.each do |g| %>
<MODAL>
<% g.requests.each do |r| %>
<%= r.date %>
<% end %>
</MODAL>
<% end %>
I need to list all my lawns in one page and then all my bookings in another page. I am writing a method in my controller to list my all items in my database but the problem is either it displays 1 in the view or it produces an inheritance error(in the view) . What I have so far is a lawn that has_many bookings (should actually be has one booking) and a booking which belongs to a lawn and everything is controlled through Activeadmin. The error I get is
undefined method `description' for
Lawn::ActiveRecord_Relation:0x007f4451b00a58> I have modified the error a little bit so it can show over here.
Here is my controller code. A lawn has a title and a description so I am not sure why I get the error. I have put 2 different methods for lawn and booking but they are both not working. Here is my controller.
def display_lawns
#lawn = Lawn.all
end
def display_status
#lawn = Lawn.where("selected = ?", "true")
#bookings = #lawn.booking
end
And here is my view file which does not seem to work with the Lawn.all I also have a similar view file for the bookings with a few changes.
<h2><%= #lawn.description %></h2>
<ul>
<% #lawn.bookings.each do |booking| %>
<li>
<%= booking.description %>
<%= button_to "Select", update_booking_path(booking_id: booking), remote: true %>
</li>
<% end %>
</ul>
A couple of hints.
Instead of
#lawn = Lawn.where("selected = ?", "true")
Is better to add a scope in your model.
#lawn is an array of objects, so use plural.
def display_lawns
#lawns = Lawn.all
end
def display_status
#lawns = Lawn.all.where("selected = ?", "true")
end
#lawns is an array, so you can't use #lawn.description
#lawn.first.description works if you need the first item of the array
<h2><%= #lawns.first.description %></h2>
<ul>
<% #lawns.each do |lawn| %>
<li>
<%= lawn.description %>
<%= button_to "Select", update_booking_path(booking_id: lawn.booking), remote: true %>
</li>
<% end %>
</ul>
Lawn.all and Lawn.where(...) return an ActiveRecord::Relation, consisting of multiple lawns.
In your view, you try to display a lawn's description via #lawn.description, but #lawn is not a single lawn object, but a collection of lawn objects, and the collection does not have a description.
Either only show one lawn object, or loop over all the objects in #lawn (and rename it to #lawns).
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 }
I was making a travel vacation application. Searching of places is based on categories from select dropdown.
But I am not able to understand the program logic. I am able to load the content in the database. but can't filter based on certain categories.
I made a scaffold called listing and included certain parameters.
In the database it has a row of 5 columns, namely, place, description, image_url, price, category.
Now, if I create another controller, search, I am not able to load a row based on a category from the select dropdown.
Search_controller.rb
def index
#categories = Listing.find_by_sql("SELECT category FROM listings GROUP BY category").map &:category
#list = params[:category].blank? ? Listing.all : Listing.find_all_by_category(params[:category])
end
index.html.erb
<% form_tag(:action => :index) do %>
<%= select_tag "category", options_for_select(#categories) %>
<%= submit_tag "Filter" %>
<% end %>
<table>
<% #list.each do |list| %>
<tr>
<td><%= list.place %></td>
</tr>
<% end %>
</table>
It does not show the select option.
Also, I tried to do this without select form
Search_controller.rb
def index
#list = Listing.select(:category).map(&:category).uniq
end
Index.html.erb
<% #list.each do |r| %>
<%= r.place %>
<% end %>
It says: undefined method `place' for "sunny":String (where "sunny" is a category)
Basically, how do you get the row based on a certain column value. And, will the logic also apply to two select dropdowns?
I know I am close, but somethings not right. Please assist me.
Thanks a lot.
You are missing = before form_tag. Should be:
<%= form_tag(:action => :index) do %>
<%= select_tag "category", options_for_select(#categories) %>
<%= submit_tag "Filter" %>
<% end %>