simple search with rails - ruby-on-rails

hy
i try to create a simple search on my application
calendar.rb
def self.search(search_condition)
search_condition = "%" + search + "%"
find( :all, :conditions => ['city like ?', search_condition])
end
calendar_controller.rb
def index
#search = #user.calendar.search(params[:search_condition])
#content_calendars = #user.calendar.all
#content_calendars_by_dates = #content_calendars.group_by(&:published_on)
#date = params[:date] ? Date.parse(params[:date]) : Date.today
end
the partial _search.html.erb
<%= form_tag root_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search_condition], :id => 'search_field' %>
<%= submit_tag "Search", :name => nil %>
<% end %
when i try i get this error:
The request method POST is inappropriate for the URL /.
i dont understand why ?
rake routes
user_calendars GET /users/:user_id/calendars(.:format) calendars#index
POST /users/:user_id/calendars(.:format) calendars#create
new_user_calendar GET /users/:user_id/calendars/new(.:format) calendars#new
edit_user_calendar GET /users/:user_id/calendars/:id/edit(.:format) calendars#edit
user_calendar GET /users/:user_id/calendars/:id(.:format) calendars#show

Your form tag needs to route to the calendar index action. Like this:
<%= form_tag(user_calendars_path(#user), :method => 'get') do %>
<%= text_field_tag :search, params[:search_condition], :id => 'search_field' %>
<%= submit_tag "Search", :name => nil %>
<% end %>
EDIT: Figured it out, here's the real problem:
Your route for calendars#create is the same as your route for calendars#index.
/users/:user_id/calendars(.:format)
You need to change your routes.rb file to differentiate between them. Traditionally the plural path goes to the index action.

Related

rails - multiple paths for a search form

I'm implementing the website. I got a problem for a search form. I upload my code, and what i want to ask is how to set the search 'path' through 'index' and 'historical' on homes_controller
Below, my code:
app/controllers/homes_controller
def index
#homes = Home.where(:category => 1).reverse
end
def historical
#homes = Home.where(:category => 2).reverse
end
app/views/layouts/application.html.erb
Below, this code is temporary code for now. I should change it.
<%= form_tag(homes_path, :method => 'get', id: "search-form" do %>
<%= text_field_tag :search, params[:search], placeholder: "검색" %>
<%= submit_tag "검색", :name => nil %>
<% end %>
Am not sure what you are supposed to do here
But as per the question - I can give a solution to your problem
Keep an instance variable in your controller actions - like this
app/controllers/homes_controller
def index
#homes = Home.where(:category => 1).reverse
#search_path = "path you want to give"
end
def historical
#homes = Home.where(:category => 2).reverse
#search_path = "path you want to give"
end
and in your layout you can use it like this
app/views/layouts/application.html.erb
<%= #search_path.present? %>
<%= form_tag(#search_path, :method => 'get', id: "search-form" do %>
<%= text_field_tag :search, params[:search], placeholder: "검색" %>
<%= submit_tag "검색", :name => nil %>
<% end %>
<% end %>

creating a form to route a method inside controller

I am trying to create a form that redirects to a method called accept_item on the form controller. My issue is that it's not going through the accept_item method when I submit the form.
form_controller.rb
def accept
#form = Form.find(params['id'])
end
def accept_item
redirect_to inventories_path
end
accept.html.erb
<%= form_tag accept_item_forms_url do %>
<% #form.items.each do |i| %>
<%= label_tag 'Item Name' %>
<p><%= i.name %></p>
<%= label_tag 'Quantity' %>
<p><%= text_field_tag 'quantity', i.quantity %></p>
<% end %>
<%= submit_tag 'Accept', class: 'btn btn-default btn-about pull-left', data: {confirm: 'Are you sure you want to accept?'} %>
<% end %>
routes.rb
resources :forms do
collection do
get :accept_item, :as => :accept_item
end
end
Error Message
No route matches [POST] "/forms/accept_item"
The form_tag helper uses the HTTP POST method by default. You defined your routes with get:
get :accept_item, :as => :accept_item
You should use post instead:
post :accept_item, :as => :accept_item
Also I don't think you need the as: :accept_item part, unless you're going to use accept_item_url instead of accept_item_forms_url.
just remove :as => :accept_item, and change method to post
post :accept_item
You will get /foo when using :as => 'foo'.

Routing a resource to controller

How do you route a resource to its controller? I am using the resource in an edit page for a different model, so my actions are being routed to its model controller first.
This edit page requests from
class Grandstreamers::ResellersController < ApplicationController
def new
end etc...
I am trying to route the requests to here instead:
Grandstreamers::CertificatesController < ApplicationController
def new
end
def update
end etc...
This is my form under views/grandstreamers/resellers/edit.html.erb
<%= form_for #untrained, :url => certificates_update_path(#untrained) do |f| %>
<p> Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#current_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Un-Train", class: "btn btn-large btn-primary" %>
<% end %>
<%= form_for #trained, :url => certificates_create_path(#trained) do |f| %>
<p> Non-Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#non_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Train", class: "btn btn-large btn-primary" %>
<% end %>
My route is:
resources :certificates
Note that the
:url => certificates_create_path
is not correct and not working. Is there a way to specify this route in my routes.rb file or in my form? Thank you
EDIT
This is my resellers_controller edit() which is routes to first.
#trained = Certificate.new(params[:certificate])
#Trying to get to certificates_controller update. Then update the :attend to "No"
##untrained = Certificate.new(params[:certificate])
##untrained = Certificate.find(params[:id])
##untrained = Certificate.find_by_user_id(params[:id])
#untrained is not defined, I am not sure how to get it to just go to my certificate controller. For #trained I can define it since its not made yet and does not give me errors when it cant find a correct value.
My certificates controller which uses create() but cannot get to update()
def create
#trained = Certificate.new(params[:certificate])
if #trained.save
#trained.update_attributes(attend: "Yes")
end
redirect_to grandstreamers_resellers_path
end
def update
#untrained = Certificate.find(params[:id])
#untrained.update_attributes(attend: "No")
redirect_to grandstreamers_resellers_path
end
Major Issue
The instance variable #trained and #untrained need to be defined somehow in reseller_controller. What can I define them as to load the edit page?
Part Solution
I defined this is in my resellers_controller and it loads the edit page now.
#untrained = User.find(params[:id])
Now I get this error:
No route matches [PUT] "/certificates.1"
I believe the problem is you need to let routing know the full name to the controller.
From the Rails routing guide:
scope module: 'Grandstreamers' do
resources :certificates
end
Use these paths when creating the form:
<%= form_for #untrained, :url => certificate_path(#untrained), :method => :put do |f| %>
<%= form_for #trained, :url => certificates_path, :method => :post do |f| %>
use this his routes.rb file
namespace :grandstreamers do
resources :certificates
end

undefined local variable or method `toggle_follow_path'

I'm getting this error undefined local variable or methodtoggle_follow_path'` in the view folder .I probably got something wrong with the method or the use off form_tag + toggle_follow_path any help would be welcome thank you . by the way the goal of the toggle follow is to follow or un follow some one.
in the route file
match '/:username/toggle_follow', to: 'home#toggle_follow'
home controller
def toggle_follow
#user = User.find_by_username(params[:username])
if current_user.is_friend? #user
flash[:notice] = "You are no longer following ##{#user.username}"
current_user.remove_friend(#user)
else
flash[:notice] = "You are now following ##{#user.username}"
current_user.add_friend(#user)
end
redirect_to user_flits_path(#user)
end
view
<h1><%= image_tag #user.gravatar_url, :align => "top" %> <%= #user.username %></h1>
<%= form_tag toggle_follow_path, :method => :post do %>
<% if current_user.is_friend? #user %>
<%=h submit_tag "Following" , :class => "button" %>
<% else %>
<%=h submit_tag "Follow" , :class => "button" %>
<% end %>
<% end %>
<%=h render :partial => "flits_list", :locals => {:flits => #flits }%>
Use :as option for match to specify the desired helper's name:
match '/:username/toggle_follow', to: 'home#toggle_follow', as: 'toggle_follow'
This way both toggle_follow_path and toggle_follow_url will be created.
It needs to take in a :username param.
Try this:
toggle_follow_path(:username => "johndoe") # fill in the correct username.

update_attributes with none-standard form

I have cobbled together a form due to some oddities in my code and routes. Things work for adding data to the database, but I can't quite seem to figure out how to update data. Here is some code.
new.html.erb
<% form_tag '/list' do %>
Episodes Completed:
<%= text_field_tag "completed" %>
Watch Status
<%= collection_select(nil, 'id', #show_status, :id, :state) %>
<%= hidden_field_tag('show_id', #show.id) %>
<%= submit_tag 'Add' %>
<% end %>
edit.html.erb
<% form_tag("/list/#{#show_completion.show.id}", :method => :put ) do %>
Episodes Completed:
<%= text_field_tag "completed", #show_completion.episodes_completed %>
Watch Status
<%= collection_select(nil, 'id', #show_status, :id, :state) %>
<%= hidden_field_tag('show_id', #show_completion.show.id) %>
<%= submit_tag 'Edit' %>
<% end %>
Here is the controller's Create and Update methods
def create
#show_completetion = ShowCompletionStatus.new
#show_completetion.user_id = current_user.id
#show_completetion.episodes_completed = params[:completed]
#show_completetion.status_state_id = params[:id]
#show_completetion.show_id = params[:show_id]
#show_completetion.save
end
def update
#show_completion = ShowCompletionStatus.find(params[:id])
#show_completion.episodes_completed = params[:completed]
#show_completion.status_state_id = params[:id]
#show_completion.show_id = params[:show_id]
if #show_completion.update_attribute('episodes_completed', params[:completed])
redirect_to "/list/#{current_user.username}"
else
redirect_to "/list/#{params[:id]}/edit"
end
end
Here are my routes for these:
match "list/" => "list#create", :via => :post
match "list/new/:show_id" => "list#new", :constraints => { :show_id => /[0-9]+/ }
match "list/:id/edit" => "list#edit", :constraints => { :id => /[0-9]+/ }, :via => :get
match "list/:id" => "list#update", :constraints => { :id => /[0-9]+/ }, :via => :put
I have been trying different things to get this to work for the better part of 4 hours now. I think I am just missing something, but I just can't see it.
Is there a better way to do the form that makes it work better?
Any help is appreciated.
I solved this issue by making a hash and passing it to the update attributes with the key value pairs of what the objects attributes would be. Since updates_attributes takes a hash and not an object it was a simple solution once the connection was made.
Try to replace your update_attribute call for a save call.
Also, if you're writing everything from scratch instead of using the builtins, try to use save! instead of save: it will raise an exception if it fails, unlike the plain save that just returns false.

Resources