Is there anyway to change sort_link output params? - ruby-on-rails

I wanna make a page that contains more than one tables. Each table is ajax filtered table that can be sorted using metasearch. This is sorting link for each table.
Controller SomeController:
def index
#search = FirstTable.search(params[:search])
#first_tables = #search.all
#search_second_table = SecondTable.search(params[:search_second_table])
#second_tables = #search_second_table.all
...
end
View:
# First table
sort_link #search, :some_attribute, "Some Attribute"
#=> www.example.com/some_controller?search[meta_sort]=some_attribute.asc
# Second table
sort_link #search_second_table, :some_attribute, "Some Attribute"
#=> www.example.com/some_controller?search[meta_sort]=some_attribute.asc
I have no idea why the sort_link outputting the same link or maybe I've made some mistake. Is there anyway to change the output of second_table sort_link to be like this.
#=> www.example.com/some_controller?search_second_table[meta_sort]=some_attribute.asc
Thx for your help.

solved my problem using link_to. after click "Some Attribute" link, change the "meta_sort" params to desc using jquery, right after ajax response return successfully. link_to "Some Attribute", :controller => "some_controller", :search_second_table => {:meta_sort => "some_attribute.asc"}

Related

How to I make a drop down beside a search box that searches the specific field selected in rails?

Okay so im new to this site but this is what I have:
Report.rb
def self.search(search)
if search
where('JOBLETTER_CD_NUMBER LIKE ? AND DATE LIKE? AND CUST LIKE ?', "%#{search}%")
else
scoped
end
end
end
index.html.erb
select_tag "search", options_for_select([ "Job Letter and CD #", "Date", "Cust", "Job", "Date shipped", "Date billed", "Billed by" ], params[:search])
form_tag reports_path, :method => 'get' do
text_field_tag :search, params[:search], :class=> "form-search", :align => "right"
<%= submit_tag "Search", :JOBLETTER_CD_NUMBER => nil, :class => "btn btn-success", :align => "right"
reports controller
def index
#report = Report.paginate(:per_page => 1, :page => params[:page])
#report = Report.search(params[:search]).paginate(:per_page => 1, :page => params[:page])
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #views }
end
end
The only field it will search is the Job Letter and CD # field I need it to allow me to search whatever is selected in the drop down box. Btw I am using bootstrap fro js and css functions.
Your query has 3 placeholders ? but passed only one argument "#{search}" - if you run it like that, what you really should be getting is an exceptions stating
ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (1 for 3) ...
Also, your select_tag is outside the form, so it won't be passed to the controller at all. If you move it into the form, you'd have to rename (e.g. to column) it since the name search is already used by the text field. Then you could pass both the column and the search parameters to your search function to construct the query.
HOWEVER, this is not safe, since nothing prevents a user to pass in any other column by manipulating the post request, and since you can't use placeholders for column names, there's a danger of SQL injection as well.
There are many solutions out there to construct searches, no need to reinvent the wheel. Take a look at the ransack gem. Here's a recent Railscast on how to use it.

How would I sort items from an array that have been chosen through checkboxes?

I want to sort the items that have been previously selected with checkboxes. If I select ratings for movies by clicking the checkboxes, it returns the movies that apply.
The end of the URL looks like this:
?ratings[PG-13]=1&ratings[G]=1
If I click on the link that orders the movies, it takes the whole list of movies and not the ones that I just targeted. So, how can I "append" "sort=title" to the ratings in the URL?
I have a feeling it's something I can do in the view. My link_to is this:
%th#title_header{:class=>("hilite" if #sort == "title")}= link_to "Movie Title", :sort => "title"
and my check_box_tag is this:
= check_box_tag "ratings[#{rating}]",rating,#all.include?(rating)
In my controller, I have this:
def index
#movies = Movie.order(params[:sort])
#movies = #movies.where(:rating => params[:ratings].keys) if params[:ratings].present?
#sort = params[:sort]
#all = (params[:ratings].present? ? params[:ratings] : [])
end
(I know, my "where" query is vulnerable to SQL injection, it's temporary, I'm just trying to conceptualize the whole thing.)
You need to pass an extra hash at the end of link_to ,it chains the queries in the url:
link_to "Movie Title", movies_path(:sort => "title", :ratings => params[:ratings])
Brilliant!

How to display Rails select field values rather than stored integers in other views

I'm using a select field in a Rails app that is NOT tied to a related model, but stores integer values for a static series of options , i.e.,
<%= select (:this_model, :this_field, [['Option1',1],['Option2',2],['Option3',3],['Option4',4]] ) %>
In a show/ index view, if I want to display the option text (i.e. Option1, Option2, etc) rather than the integer value stored in the database, how do I achieve this?
Thanks for helping a noob learn the ropes!
EDIT
Based on Thorsten's suggestion below, I implemented the following. But it is returning nil, and I can't figure out why.
Invoice model:
##payment_status_data = { 1 => "Pending Invoice" , 2 => "Invoiced" , 3 => "Deposit Received", 4 => "Paid in Full"}
def text_for_payment_status
##payment_status_data[payment_status]
end
Invoice show view:
Payment Status: <%= #invoice.text_for_payment_status %>
In the console:
irb > i=Invoice.find(4)
=> [#<Invoice id: 4, payment_status: 1 >]
irb > i.text_for_payment_status
=> nil
I've tried defining the hash with and without quotes around the keys. What am I missing?
something like this would work:
<%= form_for #my_model_object do |form| %>
<%= form.label :column_name "Some Description" %>
<%= form.select :field_that_stores_id, options_for_select({"text1" => "key1", "text 2" => "key2"}) %>
<% end %>
Update
If you later want to display the text you can get it from a simple hash like this:
{"key1" => "text 1", "key2" => "text2"}[#my_object.field_that_stores_id]
But you better store this hash somewhere in a central place like the model.
class MyModel < ActiveRecord
##my_select_something_data = {"key1" => "text 1", "key2" => "text2"}
def text_for_something_selectable
##my_select_something_data[field_that_stores_id]
end
end
Then you can use it in your views like
#my_object.text_for_something_selectable
There are many possible variations of this. But this should work and you would have all information in a central place.
Update
Ok, I used something similar for our website. We need to store return_headers for rma. Those need to store a return reason as a code. Those codes are defined in an external MS SQL Server Database (with which the website exchanges lots of data, like orders, products, and much more). In the external db table are much more return reasons stored than I actually need, so I just took out a few of them. Still must make sure, the codes are correct.
So here goes he model:
class ReturnHeader < AciveRecord::Base
##return_reason_keys = {"010" => "Wrong Produc",
"DAM" => "Damaged",
"AMT" => "Wrong Amount"}
def self.return_reason_select
##return_reason_keys.invert
end
def return_reason
##return_reason_keys[nav_return_reason_code]
end
end
Model contains more code of course, but that's the part that matters. Relevant here is, that keys in the hash are strings, not symbols.
In the views i use it like this:
In the form for edit:
<%= form_for #return_header do |form| %>
<%= form.label :nav_return_reason_code "Return Reason" %>
<%= form.select :nav_return_reason_code, options_for_select(ReturnHeader.return_reason_select, #return_header.nav_return_reason_code) %>
<% end %>
(Maybe no the most elegant way to do it, but works. Don't know, why options_for_select expects a hash to be "text" => "key", but that's the reason, why above class level method returns the hash inverted.)
In my index action the return reason is listed in one of the columns. There I can get the value simply by
#return_headers.each do |rh|
rh.return_reason
end
If you have trouble to get it run, check that keys a correct type and value. Maybe add some debug info with logger.info in the methods to see what actual data is used there.

how to do two search in the same page with meta_search?

I have two list in a page, one for a model_1 and another for a model_2. When I click the sort_link of a column meta_search send the param "search[meta_sort]=column_name.asc". The problem is in the controller because the two models get filtered with the same search parameters:
#in the controller
#search_for_model_1 = Model1.search(params[:search])
#model_1s = #search_for_model_1.all
#search_for_model_2 = Model2.search(params[:search])
#model_2s = #search_for_model_2.all
#in the view
<%= sort_link #search_for_model_1, :name %>
<%= sort_link #search_for_model_2, :name %>
the sort_links are in different html tables, one showing model_1 fields and the another showing model_2 fields, when I click in any column name link, the param I get in the controller is params[:search], I have no way to know if the column link was clicked from model_1 or model_2 html table.
I want change the param name "search" for something like "search_for_model_name" then in the controller:
#in the controller
#search_for_model_1 = Model1.search(params[:search_for_model_1])
#model_1s = #search_for_model_1.all
#search_for_model_2 = Model2.search(params[:search_for_model_2])
#model_2s = #search_for_model_2.all
I could not find the way to change the param name using the helper method sort_link that meta_search provide. Or is there a different manner to do this?
sort_link uses the :as option just like form_for
<%= form_for #search, :as => :q do |f| %>
<%= sort_link #search, :field, :as => :q
#search = Model.metasearch(params[:q])
So do that with different names for each model.
most likely you just do something like this
:search_for_model_2 => :search_field
but I can't say for sure without seeing your view.
graywh's answer is not working for sort_link, this is the correct solution:
#in the controller
#search_for_model_1 = Model1.search(params[:model_1], :search_key => :model_1)
#search_for_model_2 = Model2.search(params[:model_2], :search_key => :model_2)

Rails/ajax - whitespace and request.raw_post

I am starting to learn Ajax with rails.
I have a catalog index page with a text_field_tag querying db if it finds similar "section" results.
Index.html.erb
<h1>Catalogs</h1>
<label>Search by Section:</label>
<%=text_field_tag :section %>
<%= observe_field(:section,
:frequency=> 0.1,
:update=> "article_list",
:url=>{ :action => :get_article_list }) %>
<div id="article_list"></div>
Catalogs_controller.rb
def index
end
def get_article_list
#section = request.raw_post.split(/&/).first
#catalogList = "<ol>"
Catalog.find(:all, :conditions => ["section = ?", #section]).each do |catalog|
#catalogList += "<li>" + catalog.title + "</li>"
end
#catalogList += "</ol>"
render :text => #catalogList
end
Question:
request.raw_post renders something like:
xml&authenticity_token=tgtxV3knlPvrJqT9qazs4BIcKYeFy2hGDIrQxVUTvFM%3D
so I use
request.raw_post.split(/&/).first
to get the section query ("xml"). It works, however how can I do if the query have a whitespace. (like "Open Source") In fact, I have Open Source sections in my db, but request.raw_post.split(/&/).first renders Open%20Source. How can I manage this? Did I have to use a full text search engine to achieve it or there is another way?
Thanks a lot for your explanation!
Look over your logs, in them you will see the post and the params being passed. You should not need to do your own query-string splitting. You should be able to use params[:section] to get the post data.
As your comment implies, there's something missing. Your observe_field needs to tell the Rails helper what to do. Check out: http://apidock.com/rails/ActionView/Helpers/PrototypeHelper/observe_field. Anyhow, you'll want to do something like:
observe_field(... # lots of parameters
:with => 'section'
)
And that should give you params[:section].

Resources