Unable to search queries from database in rails 3 - ruby-on-rails

I am working on rails to search the desired results. I have a table called coordinates, and I want a search form for that my model.rb
class Coordinates<ActiveRecord::Base
attr_accessible :city , :latitude, :longitude
end
coordinates_controller.rb
class CoordinatesController<ApplicationController
def show
#coordinates=Coordinates.where("city = ?", params[:search]).all
end
end
index.html.erb
<%= form_tag({controller: "coordinates", action: "show"}, method: "get") do %>
<%= label_tag(:coordinates,"search for:") %>
<%= text_field_tag(:show) %>
<%= submit_tag("search") %>
<% end %>
search.html.erb
<%= form_for #coordinates.search do |coordinates| %>
<ul>
<li><%= coordinates.latitude %></li>
<li><%= coordinates.longitude %></li>
<li><%= coordinates.longitude %></li>
</ul>
<% end %>
but I am getting this error:
undefined method `search' for []:Array
.. please help

To begin, try changing the form code in index.html.erb from:
<%= form_tag({controller: "coordinates", action: "show"}, method: "get") do %>
<%= label_tag(:coordinates,"search for:") %>
<%= text_field_tag(:show) %>
<%= submit_tag("search") %>
<% end %>
To:
<%= form_tag({controller: "coordinates", action: "show"}, method: "get") do %>
<%= label_tag(:search,"search for:") %>
<%= text_field_tag(:search) %>
<%= submit_tag("Search") %>
<% end %>
This will populate params[:search] with the value of the text field. Currently you are passing your query as params[:show].
Next, try changing your search results view to:
<% #coordinates.each do |coordinates| %>
<ul>
<li><%= coordinates.latitude %></li>
<li><%= coordinates.longitude %></li>
<li><%= coordinates.longitude %></li>
</ul>
<% end %>
This iterates over the #coordinates collection returned by your controller.

From the line
undefined method 'each' in nil:Nilclass
It seems that there are no coordinates for the city you looking for in your database
after the call
#coordinates=Coordinates.where("city = ?", params[:search]).all
check #coordinates.nil? and #coordinates.count to see if this is the case
And beside it is a better practice to check it before using it - so you can handle it in the way you want - in case that something went wrong in your DB and you don't want the user to get such errors on production

Related

Instance variable nil in one view, not in another

I'm working on a project in Ruby on Rails (Ruby v.2.2.8, Rails 5.1.4) and have encountered a very strange issue.
For my show method in the controller, I have:
def show
#county = County.find(params[:id])
end
And it works. For update, I have.
def update
#county = County.find(params[:id])
if #county.update(county_params)
redirect_to #county
else
render 'edit'
end
end
In my 'edit', I consistently get an error that #county is nil. The error page indicates that the parameters are being passed as:
{'id'=>4}
as an example. When I use find_by from the rails console, the item is found.
Is there something here I'm missing?
ETA: View Code
<%= form_with model: #county, local: true do |form| %>
<% if #county.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#county.errors.count, "error") %> prohibited
this county from being saved:
</h2>
<ul>
<% #county.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= form.label :name %><br>
<%= form.text_field :name %>
</p>
<p>
<%= form.label :shortname %><br>
<%= form.text_field :shortname %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
ETA Routes for Counties:
counties GET /counties(.:format) counties#index
POST /counties(.:format) counties#create
new_county GET /counties/new(.:format) counties#new
edit_county GET /counties/:id/edit(.:format) counties#edit
county GET /counties/:id(.:format) counties#show
PATCH /counties/:id(.:format) counties#update
PUT /counties/:id(.:format) counties#update
DELETE /counties/:id(.:format) counties#destroy
The error occurs at /counties/:id/edit
How is your edit action in your controller?
You should define #county as well
def edit
#county = County.find(params[:id])
end

Linking to basket/cart in ruby on rails

I have a menu in my header that has a show basket and a login button, each work when the code is placed in separately but not when both lines are in the file.
I'm using devise for the users.
Is there a better way to link to the current basket?
<li><%= link_to basket_path(#basket.id) do %>
<%= image_tag "/assets/viewBasket.png" %>
</li>
<% end %>
<% if signed_in? %>
<li><%= link_to edit_user_registration_path do%>
<%= image_tag"/assets/my_account.png" %></a></li>
<% end %>
<li><%= link_to destroy_user_session_path do%>
<%= image_tag"/assets/logout.png" %></li>
<%end%>
<% else %>
<li><%= link_to new_user_session_path do%>
<%= image_tag"/assets/loginRegisterBtn.png" %></li>
<% end%>
<% end %>
If I run on its own this works but not with the code after.
<li><%= link_to basket_path(#basket.id) do %>
<%= image_tag "/assets/viewBasket.png" %></li>
<% end %>
I think its to do with the way the current basket is set with the session id in the current_basket model.
module CurrentBasket
private
def set_basket
#basket = Basket.find(session[:basket_id])
rescue ActiveRecord::RecordNotFound
#basket = Basket.create
session[:basket_id] = #basket.id
end
end
The closing of <li> must be after the end of the link, like this:
<li>
<%= link_to basket_path(#basket.id) do %>
<%= image_tag "/assets/viewBasket.png" %>
<% end %>
</li>
I used the answer above which helped with one issue, however, I found that I had defined only the shop and index page. Removing this and it now works.
include CurrentBasket
before_action :set_basket, only: [:index, :shop]

Unable to get the value of a variable inside Rails erb tags

I want to understand the erb usage. In the below code I am unable to figure out how to get the value of (group.id) in the if clause using the erb tags.
This probably has a very basic solution but I am unable to get proper answers.
The below code gives me syntax error.
<% current_user.favorite_groups.to_a.each do |group| %>
<%= if (group.id).newfavorite_texts.exists?(id: text.id) %>
<%= group.name %>
<%= link_to # do something %>
<% else %>
<%= group.name %>
<%= link_to # do something else %>
<% end %>
<% end %>
Thanks in advance.
You should be get going with the below code
<% current_user.favorite_groups.to_a.each do |group| %>
<% if group.newfavorite_texts.exists?(id: text.id) %>
<%= group.name %>
<%= link_to # do something %>
<% else %>
<%= group.name %>
<%= link_to # do something else %>
<% end %>
<% end %>

How to customise rails validation error messages with a nested form setup

I have a form with a nested object something like this:
<%= form_for(#person) do |f| %>
<% if #person.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#person.errors.count, "error") %> prohibited this record from being saved</h2>
<ul>
<% #person.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render 'person_fields', f: f, :person => #person %>
<%= f.fields_for :posts do |builder| %>
<%= render 'post_fields', f: builder %>
<% end %>
<br />
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The thing is the validation error messages come up in the format {attribute}{message}, i.e the regular full_messages format. The {attribute} also includes the model name which isn't what I want, I just want to display the attribute and the message.
I'm thinking I can potentially us the rails internationalisation api but could use some guidence; has anyone else managed to do this?
I worked out how to this... just for reference, here's my solution:
<%= form_for(#person) do |f| %>
<% #person.errors.messages.each do |msg| %>
<% msg[1].each do |m| %>
<% if msg[0].to_s.split(".")[-1] == "base" %>
<li><%= m %></li>
<% else %>
<li><%= msg[0].to_s.split(".")[-1].humanize.titlecase %> <%= m %></li>
<% end %>
<% end %>
<% end %>
<%= render 'person_fields', f: f, :person => #person %>
<%= f.fields_for :posts do |builder| %>
<%= render 'post_fields', f: builder %>
<% end %>
<br />
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I've used the custom-err-msg plugin in the past and had a lot of success.

Stuck Understanding Link_to

I'm really struggling to understand how to link_to a parent from with a loop.
My milestones belong_to my orders and my orders have many milestones.
In my orders index, I have a simple calendar (table_builder) which lists all my milestones.
<%= calendar_for #milestones, :year => #date.year, :month => #date.month do |t| %>
<%#= calendar_for(#orders, :year => 2009, :month => 1) do |t| %>
<%= t.head('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') %>
<%= t.day(:day_method => :milestone_due) do |date, orders| %>
<%= date.day %>
<ul>
<% for milestone in orders %>
<li><%= link_to milestone.name, order_path %> </li>
<% end %>
</ul>
<% end %>
<% end %>
This all works swimmingly well but the link doesn't work - I need it to link back to the parent order, not the milestone. It's driving me crazy now!
In my controller, I tried putting:
#milestoneorder = Order.find(params[:id])
But that says it can't find an order without an id.
I'm obviously missing something really basic here.
You need to tell order_path which Order to link back to:
<%= link_to milestone.name, order_path(milestone.order) %>
You could probably just shorten it to this too:
<%= link_to milestone.name, milestone.order %>
UPDATE
If there's a chance some of your milestones don't have orders, you can try something like this:
<% if milestone.order %>
<%= link_to milestone.name, order_path(milestone.order) %>
<% else %>
<%= milestone.name %>
<% end %>
It doesn't sound like you have a route setup for order.
In the routes.rb file
resources :orders
or if you do, you aren't passing in an id for the order.
link_to "link text", order_url(:id => #order)
link_to "link text", order_url(#order) # <== shortened
lastly, the problem may be that order is nil. If it is nil, you will also get the 'can't find route' error.
UPDATE
<% orders.each do |order| %>
<li><%= link_to milestone.name, order_path(order) %> </li>
<% end %>
UPDATE 2
The problem is in the names. I think that you are getting get milestones from t.day not orders.
<%= t.day(:day_method => :milestone_due) do |date, milestones| %>
<%= date.day %>
<ul>
<% for milestone in milestones %>
<li><%= link_to milestone.name, order_path(:id => milestone.order_id) %> </li>
<% end %>
</ul>
<% end %>

Resources