Display title instead of id from search results - ruby-on-rails

I have spent hours on this single problem, I am desperate for help.
The below html displays the correct car name and the car.manufacture_id displays the correct manufacture id, except I need to display manufacture.name and can not figure out how to do that. How do I display car.manufacture.name?
search.html.erb
<% #cars.each do |car| %>
<%= car.manufacture_id %>
<%= link_to car.name, manufacture_path(car.manufacture_id) %>
<% end %>
search_controller.rb
def search
if params[:q].nil?
#cars = []
#manufactures = []
else
#cars = Car.search params[:q]
#manufactures = Manufacture.search params[:q]
end
end

What do your car and manufacture models looks like, can you show the code for them? The schemas would help too. If your models are setup right car.manufacture.name should have worked.
If you do
<% #manufactures.each do |manufacture| %>
<%= manufacture.id %>
<%= manufacture.name %>
<% end %>
Does this work?
Also this might work, if the manufacturers are being found by Manufacture.search params[:q]
<%= #manufactures.find(car.manufacture_id).name %>
or if they are not
<%= Manufacture.find(car.manufacture_id).name %>

Related

Narrowing search with ransack

I've got workers, workers has many posts. I want to be able to search for a worker, displaying all his posts, then narrow down to the date the posts where made. I can search by name of the worker but when I try to search for date aswell it just displays all posts for that worker (if the date exists in one post).
what I'm trying to run with:
controller:
#q = Worker.ransack(params[:q])
#workers = #q.result.order(name: :asc).includes(:posts).uniq
view:
<%= search_form_for #q do |f| %>
<%= f.label :name_cont %>
<%= f.search_field :name_cont %>
<%= f.label :posts_date_start %>
<%= f.search_field :posts_date_start %>
<%= f.submit %>
<% end %>
<% #workers.each do |worker| %>
<% worker.posts.group_by { |t| t.date.to_time.beginning_of_month }.each do |month, posts| %>
<some table header logic>
<% posts.each do |post| %>
<table content>
Unless you created a custom predicate of start, that will not work.
From your group_by statement I can see that your posts has a date field. If you wanted posts only for the date specified you would use the eq predicate
<%= f.search_field :posts_date_eq %>
If you need to massage your user input, I would look into making a custom predicate you can look at how to do that here -> creating custom predicates
EDIT
To test parsing your date field string into a date put
begin
params[:q][:posts_date_eq] = Date.parse(params[:q][:posts_date_eq])
rescue
# no param present
end
before your search object
#q = Worker.ransack(params[:q])
I solved it like this
instead of
<% worker.posts.group_by { |t| t.date.to_time.beginning_of_month }.each do |month, posts| %>
I did
<% Post.search_post(params[:search_post]).search_post_present(params[:search_post_present]).where(worker_id: worker.id).order(date: :asc).group_by { |t| t.date.to_time.beginning_of_month }.each do |month, posts| %>
that pointed to a search hepler in post.rb
def self.search_post(search_post)
if search_post
where('date LIKE ?', "%#{search_post}%")
else
all
end
end
I then overlapped the forms for both ransack and this search, so both are run with the same submit button, and that worked just fine.

Rails 4 retrieve nested attributes for display in an index.html.erb

Just looking to find out how to retrieve nested images for display on my front page. I have no problems with a standard model but have been unable to find how to bring has_many nested attribute through. All my nested Forms work fine just have neglected the front end.
eg. product has nested product_images. This doesn't look like a clever way of doing it as the last five images uploaded wont necessarily be related to the last five products added.
Could someone please share an example.
cheers
app/controller/home_controller.rb
class HomeController < ApplicationController
def index
#products = Product.last(5)
#product_images = ProductImage.last(5)
end
end
app/views/home/index.html.erb
<% #products.each do |pd| %>
<div><%= pd.product_name %>
<% end %>
<% #product_images.each do |pd| %>
<%= image_tag (pd.product_image(:medium)) %>
<% end %>
</div>
You can try this:
app/controller/home_controller.rb
class HomeController < ApplicationController
def index
#products = Product.last(5)
#product_ids = #products.collect(:id)
#product_images = ProductImage.where(:id => #product_ids).last(5)
end
end
app/views/home/index.html.erb
<% #products.each do |pd| %>
<div><%= pd.product_name %>
<% end %>
<% #product_images.each do |pd| %>
<%= image_tag (pd.product_image(:medium)) %>
<% end %>

If two DateTime stamps are the same in Rails

I have created a simple appointment system, and I now need to display something inside a loop if there's two or more appointments with the same date and time. The appointments are displayed in order of time, so they're just appearing one after the other.
Controller
def index
#todays_apps = current_user.appointments.order(time ASC)
end
View
<% #todays_apps.each do |app| %>
<%= app.business_name %>
<%= app.business_address %>
<%= app.time %>
<% end %>
I'm looking to display a message or icon the appointment shares a date and time with another appointment. Tried a collection of things with no luck.
You can group your collection by time and modify your iteration accordingly. You can group it like
#todays_apps.group_by(&:time)
The outcome will be something like
=> { timestamp1 => [app1,app2], timestamp2 => [app3], timestamp3 => [app4]}
Or you can try a quick hacky way like:
<% previous_time = nil %>
<% #todays_apps.each do |app| %>
<%= app.business_name %>
<%= app.business_address %>
<%= 'Your message or class or anything' if previous_time == app.time %>
<%= previous_time = app.time %>
<% end %>
Try Like this:
controller:
def index
#appointments = current_user.appointments.order("time ASC")
#todays_apps = #appointments.group_by(&:time)
end
View:
<% #todays_apps.each do |time, appointments| %>
<%= time %>
<% appointments.each do |appointment| %>
<%= appointment.business_name %>
<%= appointment.business_address %>
<% end %>
<% end %>
It will list all the appointments for particular time.
Thanks

Why does my search show all results with searching?

I setup a search on my Products index page with PgSearch and Will-Paginate like this:
ProductsController
def index
#products = Product.text_search(params[:query]).page(params[:page]).per_page(5)
end
Products Model
include PgSearch
pg_search_scope :search,
def self.text_search(query)
if query.present?
search(query)
else
scoped
end
end
Product index page
<%= form_tag products_path, method: :get do %>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search", name: nil %>
<% end %>
<% if #products.blank? %>
No Results
<% else %>
<% #products.each do |product| %>
<%= product.name %>
<% end %>
<% end %>
But the problem I'm having now is that when I go to the Product index page, it shows all of the products when I want it to show nothing until a search is done. If the search is blank, return No Results but when you first hit the page it should show nothing. How would this be done?
You probably want to only run a text_search when a search parameter is present. You can put this logic into the view, the controller, or in the model.
In the view
<% if params[:query].present? %>
<% if #products.blank? %>
No Results
<% else %>
<% #products.each do |product| %>
<%= product.name %>
<% end %>
<% end %>
<% end %>
In the controller
def index
if params[:query].present?
#products = Product.text_search(params[:query]).page(params[:page]).per_page(5)
else
#products = Product.none # NOTE: Rails 4 only
end
end
In the model
# create a new method to encapsulate this search logic then use it in the controller
def self.search(value)
if value.present?
Product.text_search(value)
else
Product.none # NOTE: Rails 4 only
end
end
The old saying goes "fat model, skinny controller" so you might want to opt for the model method which will keep your controller and views simpler.
Put your display logic inside an if statement:
<% if params[:query].present? %>
<% if #products.blank? %>
No Results
<% else %>
<% #products.each do |product| %>
<%= product.name %>
<% end %>
<% end %>
<% end %>
Although I'm not familiar with how pg search works, you could do something like this in your method.
It's a nice refactoring as well as it avoids checking for existence and making decisions on params (code smell)
def self.text_search(query = "")
search(query)
end
As I said, not sure how pg_search works. Maybe when you browse for nothing, it returns all records. If that's the case, you can just have it return an empty array. Something like this would do
def self.text_search(query)
return [] if query.nil?
search(query)
end

Rails filtering row by column using select dropdown

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 %>

Resources