Setting default search parameter on Ransack for rails - ruby-on-rails

I've been wracking my brain over this but can't get it. I feel like the answer is probably obvious.
What I'm trying to do is the following:
I have an index controller which lists a series of Jobs which I can search using Ransack. Each job has a completion date which either has a date in it or is null (unfinished). Currently, the search itself works great. I would like to make it so that the index page loads up showing only the unfinished work, but I also want it to work so that when someone does run a search, returns results for both finished and unfinished work.
Any help would be greatly appreciated. In the code below, :actual is the name of the field with the completion date. I also was looking around the web and thought that maybe something like the DEFAULT_SEARCH_PARAMETER={} that I have in the Job model might work but I couldn't seem to get it to.
Here is the code:
class Job < ActiveRecord::Base
DEFAULT_SEARCH_PARAMETER ={}
attr_accessible :items_attributes, :actual
end
def index
#search = Job.search(params[:q] || Job::DEFAULT_SEARCH_PARAMETER)
#search.build_condition
#results = #search.result
#job = #results.paginate(:per_page => 10, :page => params[:page])
end

Late to the party, but thought I'd suggest an alternate approach in case someone else comes across this.
The answer above works, but its disadvantage is that the default is not added to Ransack's search object, so - if you are using a search form - the default selection is not shown in the form.
The following approach adds the default to the search object and therefore will appear in your search form.
def index
#search = Job.search(params[:q])
#search.status_cont = 'Open' unless params[:q] #or whatever, must use Ransack's predicates here
#results = #search.result
#job = #results.paginate(:per_page => 10, :page => params[:page])
end

I think you could just apply your own filter when the search parameters don't exist:
def index
#search = Job.search(params[:q])
#results = #search.result
#results = #results.where(:your_date => nil) unless params[:q]
#job = #results.paginate(:per_page => 10, :page => params[:page])
end

Many years later I found myself with this exact problem so I thought I'd chime in with a solution I'm using. Set default search params in the controller and reverse merge them into params[:q]:
def index
default_search_params = {
status_cont: "open"
}
#search = Job.search((params[:q] || {}).reverse_merge(default_search_params))
...
end

So by default, you want the page to load with records where actual is nil. And later when the user searches you want to go back to how your search was working before.
Give this a try.
def index
#search = Job.search(params[:q] || Job::DEFAULT_SEARCH_PARAMETER)
#search.build_condition
#results = #search.result
if #results.nil?
#results=Job.find(:all, :conditions => ["actual = NULL"] )
end
#job = #results.paginate(:per_page => 10, :page => params[:page])
end

Related

Ruby on Rails: custom rendering in controller

So basically I have this for my index page:
def index
#articles = Article.paginate(:per_page => 15, :page => params[:page])
end
I implemented soft deletion, which basically works like this: there is an additional boolean column in db that is called is_active and is true by default. Deleting is rewritten to just change that to false instead of destruction, and made a page to view soft-deleted entries.
The issue: current workaround I found for paginate is to simply add
<% if article.is_active %>
in my index.html.erb. The flaw is: when I delete something it still considered there by paginate, so instead of say 15 entries I will see 14. Even worse, on undeleting page it shows same amount of blank pages, and deleted entries are on their would-be-appropriate pages (so for example first entry may end up being on page 14 instead of 1). It is not critical flaw, but I'd like to know if I can fix it without rewriting too much.
Maybe I can change something in controller so it doesn't send any entries that have true or false in that field depending on what I want to output?
Can't you just filter by this field?
#articles = Article.where(is_active: true).paginate(per_page: 15, page: params[:page])
You can use a scope or a where clause to get only active articles:
def index
#articles = Article.where("is_active = ?", true).paginate(:per_page => 15, :page => params[:page])
end

Ruby on Rails create new object with param from another

I have my search method and I want to pass my "search" to a analysis object. The search that user is looking will be the name of the analysis so as an Admin I can see the analysis and discovery what the users are most searching.
Here is my methods. My #analysis.name is always create with nil value. Does any body know how to fix that?
def search_articles
#search_param = params[:current_search][:search]
#articles = Article.where("title LIKE :search",
:search => "%#{params[:current_search][:search]}%")
search_attribute = :search
update_analysis(search_attribute)
end
def update_analysis(search)
#analysis = Analysis.create([{name: search, search_number: 1}])
end
Solution:
replace
search_attribute = :search
to
search_attribute = params[:current_search][:search]

Whats this ruby function doing

In this project I poke at, (I am PHP dev, not RoR), there is this function on a modal.
def task
#task ||= if search_key
Project.trop_fish.tasks.find(:first, :conditions => ["description like ?", "Search key: #{search_key}%"])
else
Project.trop_fish.tasks.find(:first, :conditions => ["(name = ? OR name like ?)","#{task_name}","#{task_name} {%}"])
end
end
So it's trying to find a task, from the project called trop_fish.
But whats the #task at the top.
Is it, assign the result of the finds from the if block to the #task?
Is it the same as
def task
if search_key
#task = Project.trop_fish.tasks.find(:first, :conditions => ["description like ?", "Search key: #{search_key}%"])
else
#task = Project.trop_fish.tasks.find(:first, :conditions => ["(name = ? OR name like ?)","#{task_name}","#{task_name} {%}"])
end
end
Almost, not quite. It is the same thing as this:
def task
if search_key
#task ||= Project.trop_fish.tasks.find(:first, :conditions => ["description like ?", "Search key: #{search_key}%"])
else
#task ||= Project.trop_fish.tasks.find(:first, :conditions => ["(name = ? OR name like ?)","#{task_name}","#{task_name} {%}"])
end
end
The ||= indicates that the variable will only be set to the new value if it is not already set with a different value. As some people commenting have pointed out/to put it more simply, #task will be set to the new value if it is nil or false.
This portion of the RoR tutorial by Michael Hartl is a great explanation of the ||= operator.
#pguardino brings up a good point in that a PHP programmer may not be familiar with the fact that if there is no explicit return statement within a method in ruby, it will return the last non-conditional statement in the method as it's return value, so yes, #task is being returned.
There is another bit of text in the RoR tutorial which explains why it is advantageous to use the ||= operator when returning from a method. It is useful because it means the first call to the task method will perform an operation against the database to retrieve a task, but subsequent calls to the method within the same thread will return #task without making calls to the database (since the #task variable has already been set.

How to set a 0 result in meta_search before user pressing a search button

I'm using a meta_search on my rails 3 app. By default (before pressing a search button) meta_search returns all elements of searching model. and I want to set 0 result before user pressing a search button or if search params is blank.
I am using meta_search as follows:
def index
#search = Article.search(params[:search])
if params[:search].blank?
#places = nil
else
#places = #search.all
end
end
What is the best way to set a 0 result if search params is blank ?
Thanks
I don't think that's something that Meta Search really provides out of the box but you can always cheat it.
def index
#search = Article.search(params[:search].presence || {:id_lt => 0})
#places = #search.all
end
In my opinion, your solution is good enough. It's clear about what it's doing and it doesn't access the database unnecessarily. But the code can be improved to:
def index
#search = Article.search(params[:search])
#places = #search.search_attributes.values.all?(&:blank?) ? [] : #search.all
end
Checking the hash for blank is not the way to do it. A hash like {'name_contains' => ''}, which is what you get if the form submitted is blank, will return false.
Also it's better to set #places to an empty array rather than nil. This way you don't have to check for nil and your loop will still work.

How do I create a link to a list of records where field X contains Y in Ruby on Rails?

I get the exact result I want if I change...
def index
#listings = Listing.all
end
to...
def index
#listings = Listing.where("general_use == 'Industrial'")
end
... in listings_controller.rb
The Listings index view shows a list of all Listings where the general_use field contains the word Industrial. However, I can no longer use the index view to show all listings if I do this.
I want to add a link at the top of my listings index view that narrows the listings down from "all" to just the "industrial" listings.
I don't know what code should go in any, all or none of the following places:
controllers\listings_controller.rb
helpers\listings_helpers.rb
models\listing.rb
views\listings\index.html.erb
config\routes.rb
Any help would be greatly appreciated.
Thanks,
Chip
Simple, use a GET parameter:
def index
if params[:use]
#listings = Listing.find(:all, :conditions => {:general_use => params[:use]})
else
#listings = Listing.all
end
end
In your view, add a link to ?use=industrial and you're all set.

Resources