I am using friendly_id so that I can create such URLs:
/search/france/weekly/toyota-95
My routes:
scope to: 'search#show' do
get '/search/:car_country_id/:rental_type_id/:car_group_id', as: 'search_country'
end
At the search#show view I have a form:
<%= form_tag search_country_path, :method => :get do %>
<%= select_tag(:car_country_id, options_from_collection_for_select(CarCountry.all, :slug, proc {|c| c.name }, {:selected => #country}), class: "Select-control u-sizeFull") %>
<%= submit_tag t('shared.search'), class: 'btn btn-primary' %>
<% end %>
And search controller:
#country = CarCountry.friendly.find(params[:car_country_id])
So ok, my intention is to change the URL as:
/search/italy/weekly/toyota-95
But the thing is, Rails params always sending france as car_country_id when I select country from select tag and submit it.
So what should I do?
Currently, two car_country_id are sent to Rails server. You can rename one of them:
<%= select_tag(:new_car_country_id, options_from_collection_for_select(CarCountry.all, :slug, proc {|c| c.name }, {:selected => #country}), class: "Select-control u-sizeFull") %>
In your controller, you should check whether new_car_country_id exists. If it does, then redirect to the corresponding path.
Another way is to make sure that the two car_country_id are the same. You should change the form's submit path once select_tag is updated with JavaScript.
Related
I'm trying to implement a two search form_tag on a the same page, each search form is placed inside dynamic bootstrap tabs. The first one which is working is basic a search form with one field. The second one which is not working has two fields, one is the same search method as the first and the other I'm trying to get the address from the other_location field and via params[:other_location].
With the current setup the other_location field form the second form does not appear!
Both of the forms are inside partials and I am rendering them inside two dynamic bootstrap tabs like this:
<%= render 'pages/search' %>
<%= render 'pages/search_other' %>
<%= form_tag search_items_path, :method => "get" do %>
<%= text_field_tag :search, params[:search], autofocus: true,
class: "search-query search_size",
placeholder: "Enter product to search" %>
<%= submit_tag "Search", name: nil, :style => "display: none;" %>
<%end%>
<%= form_for :search_other_path, :method => "get" do |form| %>
<%= form.text_field :search, autofocus: true,
class: "search-query search_size",
placeholder: "Enter keyword to search" %>
<% form.fields_for :other_location_path, :method => "get" do |f| %>
<%= f.text_field :other_location, class: "search-query search_size",
placeholder: "Enter address to search" %>
<%= form.submit "Search", name: nil, :style => "display: none;" %>
<%end%>
<%end%>
model
def self.search(search)
return where("0=1") if search !~ /\w{4}/
where("lower(title) LIKE lower(:term)", term: "%#{search}%")
end
routes.rb
get 'search' => 'pages#search', as: 'search_posts'
get 'search' => 'pages#search_other', as: 'search_other'
get 'search' => 'pages#other_location', as: 'other_location'
controller:
def search_other
if params[:search]
#posts = Post.near(other_location,10).search(params[:search]).page(params[:page])
else
#posts = []
end
end
def other_location
other_location = params[:other_location]
if params[:other_location]
Geocoder.search(params[:other_location])
end
end
def search
if params[:search]
#posts = Post.near(action,10).search(params[:search]).page(params[:page])
else
#posts = []
end
end
On your route file:
get 'search/other' => 'pages#search_other', as: 'search_other'
get 'search' => 'pages#search_other', as: 'search_other_items'
both GET requests are going to your pages_controller.rb #search_other method. So even if you have the two form_tags sending the data to different paths (search_other_path, and search_other_items_path) it would be going to the same controler method - which is redundant.
On your actual HTML you have two form tags:
<%= form_tag search_items_path, :method => "get" do %>
and
<%= form_tag search_other_items_path, :method => "get" do %>
You have not mentioned search_items_path in your routes, so I have no idea where that's pointing to. Likely its a proper controller that works since you mentioned the first form was the only one working.
Now, your mentioned controller only has a search method. So to start you are looking at the wrong controller. You should be looking at the controller methods being referenced by the form's action.
In this case, the second form is sending it's request to search_other_items_path which according to your routes, its pointing to pages_controller.rb -> #search_other method.
You should edit your question to include code that is actually relevant. Maybe then I can actually help.
I am developing a rails application using the Ransack gem and below is the code that I have written so far to filter my database which works like a charm. Now what I am trying to do is to add additional button like filter options to my index view (where each button has pre-defined filter value). In other words, once the database is first filtered with a brand name, then I would like users to be able to further filter the database by clicking one of the buttons which has a pre-defined filter value of say 'colour = white', then rails will show all the data with the selected brand name and the colour of white).
Controller
class ProjectsController < ApplicationController
def index
#q = Project.ransack(params[:q])
#projects = #q.result(distinct: true)
#projects_count = #q.result.count
#projects = Kaminari.paginate_array(#projects).page(params[:page]).per(30)
end
Index View
<%= search_form_for #q, remote: true, :builder => SimpleForm::FormBuilder do |f| %>
<%= f.input :brand_id_eq, label: false, collection: Brand.all.map{ |f| [f.name, f.id] }, prompt: "All", input_html: { class: "form-control" } %>
<%= f.button :submit, label: "Search", input_html: { class: "btn btn-primary" } %>
<% end %>
...
<span class="data-sort all"><%= link_to "All",q: {color_cont: 'white'}, :class => 'link-sort', :remote => true, :method => :post %></span>
index.js.erb
$('#projects').html('<%= escape_javascript (render partial: 'index') %>').hide().fadeIn('slow');
The problem that I am facing with this approach using the Ransack gem is that when I click the link_to filter button, it does filter the database with the pre-defined filter value of 'white color' however it resets all the previously selected filter options.
Is my approach correct or any better way to achieve this other than using the link_to option?
SOLUTION
I finally got this working using the rail's scope method and a simple jQuery code as shown in my final code below. One thing that I did initially wrong was that I set the name of the scope same as one of my db column name which caused an error. Once I changed the scope name to 'status1', not 'stock_no', it started to work. Hope this helps.
Defined Scope
class ApplicationRecord < ActiveRecord::Base
scope :status1, -> { where( stock_no = "15251" ) }
def self.ransackable_scopes(auth_object = nil)
[:status1]
end
Index.erb
<%= f.hidden_field :status1 %>
<%= f.submit "Stock", :id => "status1", :onclick => "document.getElementById('q_status1').value = 1;", class: 'btn btn-primary status1' %>
Try this question. It is somewhat what you are trying to do, except instead of a submit button, just make yours a button for filtering. It needs to be inside your search_form_for I'm pretty sure as well. And then write a jquery function to submit when the button is clicked like:
$(document).on("turbolinks:load", function(){
$(".data-sort").on('click', function() {
$("form.your-search-form-classname").trigger('submit.rails');
});
});
UPDATE
Try removing the (boolean = true) attribute from the scope. I tested with a similar app of my own and it worked well.
UPDATE 2
I put the following in my app (where status is a column in by db just like your stock_no) and a got the correct query from my database:
<%= f.hidden_field :stock_no %>
<%= f.submit "Stock", :id => "stock_no", :onclick => "document.getElementById('q_stock_no').value = 1;", class: 'btn btn-primary stock_no' %>
scope :stock_no, -> { where( status: 2 ) }
def self.ransackable_scopes(auth_object = nil)
[:stock_no]
end
Are you sure you are putting the scope in the right model?
Replace
<%= link_to "All",q: {color_cont: 'white'}, :class => 'link-sort', :remote => true, :method => :post %>
with
<%= link_to "All",q: {color_cont: 'white', brand_id_eq: params[:q][:brand_id_eq]}, :class => 'link-sort', :remote => true, :method => :post %>
Here assumption is
Once the database is first filtered with a brand name, then I would like users to be able to further filter the database by clicking one of the buttons which has a pre-defined filter value
I've got a group which has many clients.
The moment the user wants to delete the group, he's obligated to move the clients of that group to a different group.
So i've created a little form. But I already know it's wrong. but I don't know how I should do it otherwise.
I want the form to be caught by my disband_group method in my groups controller. Extract the move_to ID etc.
This is what I have now. Which doesn't work.
(it says param not found: group on params.require(:group) which is no big surprise)
<%= form_for(#group) do |f| %>
<%= select_tag('move_to', options_for_select(current_user.groups.collect{ |u| [u.name, u.id] }), :prompt => "Choose") %>
<%= f.submit "Move" %>
<% end %>
The select_tag needs to be changed to f.select. That should do the trick.
After that if it still does not work, put a 1/0 as the first line in the method to check the parameters coming in. This will throw an exception and the page will display the parameters.
Add a route to your disband_group action (add the correct path):
post '/disband_group' => "groups#disband_group", :as => :disband_group
And then modify your form pointing to the disband_group action:
<%= form_for(:group, url: disband_group_path) do |f| %>
<%= f.select :move_to, options_for_select(current_user.groups.collect{ |u| [u.name, u.id] }), :prompt => "Choose") %>
<%= f.submit "Move" %>
<% end %>
This will add send the move_to param as follows: "group" => { "move_to" => "3" }
Take a look to this to understand how the form works.
I have a link_to in my view which is going to a URL( query string) that is created dynamically in the controller.
<%= link_to "Search Venue", #venue_search, :target => :blank %>
and in the controller I'm pulling some attributes from a model and using those values in a query to hit Yahoo's API and
#event = Event.find(params[:id])
search_values = {
:api_key => 'xxxxxxxxx',
:search_text => #event.venue_name,
:location => #event.venue_zipcode,
:radius => 100
}
#venue_search = "http://yahooapis.com/rest/?method=venue.search&" + search_values.to_query
And everything is working perfect so far.
I would like to manually enter a few more parameters into the query and I'm just wondering what would be the best direction to go.
Is there a way to create a form which some text fields that I can use to insert parameters manually into the query string and to use the submit button to call the url as a link_to?
I was thinking something like
<% form_for #venue_search(:city, :state) do |f| %>
<%= f.text_field :city %>
<%= f.text_field :state %>
<% end %>
And some how add those two new parameters to the query and then execute the query
Is that possible?
If i properly understand your question, you can use for sending 'GET' request - in such case parameters will be placed in query:
<% form_for #venue_search, :method => :get do |f| %>
<%= f.text_field :city %>
<%= f.text_field :state %>
<% end %>
Hope its help you.
A model named 'book' with attributes 'name' and 'id' is given. How can i use this collection select to call the show-action of a certain book? The one code mentioned below returns the following error message:
Couldn't find Book with ID=book_id
<% form_tag(book_path(:book_id)), :method => :get do %>
<p>
<%= label(:book, :id, 'Show Book:') %>
<%= #books = Books.find(:all, :order => :name)
collection_select(:book, :id, #books, :id, :name)
%>
</p>
<p>
<%= submit_tag 'Go' %>
</p>
<% end %>
book_path is generated once only, for the form tag itself. It won't be updated whenever your selection changes.
When you submit that form, it's going to request the following URL:
/books/book_id?book[id]=5
Since your book_path thinks book_id is the ID number you wanted, it tries to look that up. You could do what you want you by changing the code in your controller from:
#book = Book.find(params[:id])
to:
#book = Book.find(params[:book][:id])
But it kind of smells bad so be warned.
You can create a new route that is not based on the id, like
get 'books/show' # put this above your "resources :books"
and change your form to
<% form_tag books_show_path, :method => :get %>