rails modle base search with check boxes - ruby-on-rails

I am working on search functionality in rails and I want a common search method for all the site. For that I am creating a method in app controller with two parameters one is modleName and another one is fieldsArray. but am not able to make it. Please help me.
I want that I set a variable in model that on which columns I need a search as like (attr_accessible) and then I need a element which I call in view files and it gets all the columns with labels and check boxes which I set in model. and I get a result with the specific column name which I enter in search box and which columns I have selected, columns would be multiple selected.
Please help.
Thanks

Hope this helps:
Create a utility class which has your generic search method.
class Util
# modelName is a string, fields would be an array of strings, keyword is string as well
# You could either call fire search from here or from individual models
def search(modelName, fields, keyword)
query = ""
fields.size.each_with_index do |field, index|
query += "#{field} like #{keyword} "
query += " OR " if index < fields.size
end
modelName.constantize.where(query)
# Or create search method in all ur models which you want to search and
modelName.constantize.search(fields, keyword)
end
end
I haven't included the model search methods as its self explanatory as to what the method should look like.
Let me know if this helps

Related

How can I set virtual attributes in the mongoid search gem

I am having a hard time with the mongoid_search gem on a few fronts and I wonder if it is working properly. As per the instructions, I am trying to create virtual attributes so that I can search on custom keywords that I create. Here are the instructions from the web page.
You can also search in "virtual" fields by defining them as methods. This can be useful when you have a method with dynamic fields (i.e. variable schema)
class ModelWithDynamicFields
...
search_in :search_data
def search_data
# concatenate all String fields' values
self.attributes.select{|k,v| v.is_a?(String) }.values.join(' ')
end
end
Mongoid_search will run the method before save and use it's output to populate the _keywords field.
I've found that this is not the case and Im trying to find outif I am doing something wrong or if there may be a problem with the gem.
Here is my code.
class User
search_in :search_data
def search_data
["#{self.attributes["email_address"]}", "#{self.attributes["first_name"]}", "#{self.attributes["last_name"]}"]
end
What I want the output to be in the _keywords array is the output of my virtual search_data method which should be this
[allanj#gmail.com allan jones]
This should be the EXACT keywords array that I want yet, the gem keeps ignoring the output of this code and goes to the default behavior. Is there something I can do to fix this?

How do I generate all new records for a given model randomly using pre-defined options?

I'd like one of my models, Stones, to be generated at random using pre-defined options I've stored in a set of arrays and hashes. Instead of Create using params from the URL, I'd like new Stones to always be defined using this random generation process. I don't need any user input at all, except that each stone belongs to a given player.
I'm still new to rails; where should I put all this code? I know enough to be able to define the arrays and hashes and randomly select from them when I need to, but I'm not sure where and how to replace the part of the code that draws params from URLs and fills in a new record before it is saved. I know controllers are supposed to be skinny, so do I do this in the model?
Apologies if this is a duplicate. I searched extensively and couldn't find an applicable solution.
Thanks for any help!
I would create a service for this. Something like:
# app/services/stone_creator.rb
class RandomStoneCreator
RANDOM_FOOS = ['bar', 'baz', 'bat']
def self.call(user)
Stone.create!({
foo: RANDOM_FOOS.sample,
user: user
})
end
end
And then anywhere that you need a new random stone you can call it like:
random_stone = RandomStoneCreator.call(current_user)

Override gem method in rails

I want to let users add interests -TV shows in this case-, and to make sure they type a correct tv show, I'm going to search imdb first and let them select one of the returning titles.
I found this gem https://github.com/ariejan/imdb which is doing almost what I need. If I search for "The vampire diaries", it will return it and 200 extra matches.
I went through the gem and I found that he does the querying part here https://github.com/ariejan/imdb/blob/master/lib/imdb/search.rb.
def self.query(query)
open("http://akas.imdb.com/find?q=#{CGI.escape(query)};s=tt")
end
That query basically uses this link http://akas.imdb.com/find?q= and returns everything that can find given the input - movies, tv shows, episodes. Now I found a more advanced query which uses type and some other params. So I could actually return only 4 results in that case instead of 250. All I have to do is to replace that query with http://www.imdb.com/search/title?title=The%20Vampire%20Diaries&title_type=tv_series.
How do I override that search method?
You can re-open the class to override the method:
class Imdb::Search
def self.query(query)
# your custom logic here
end
end
Note that you can call super(query) in your version to get the result of the original.
You can use class_eval and put it in a decorators folder
app/decorators/imdb/search_decorator.rb
class Imdb::Search.class_eval do
def self.query(query)
end
end

Rails custom model method in where query

In my rails app I have defined in the Kid model a calculation based on the fields from the Kids DB. the method is as follows:
def flip_date
self.dob.advance(months: 10)
end
I want to use this in my controller as I have a method where I am defining something as follows:
new_kids = Kid.where(discharge_date: nil).where('flip_date > ?', Date.current.advance(year: 1).beginning_of_year)
However I keep getting the following error:
SQLite3::SQLException: no such column: flip_date: SELECT "kids".* FROM "kids" WHERE "kids"."discharge_date" IS NULL AND (flip_date < '2017-01-01')
Any ideas on how can I make this work? All help is appreciated!
If you really want to use model methods take a look at http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/select
For your case:
new_kids = Kid.where(discharge_date: nil).select{|k| k.flip_date > Date.current.advance(year: 1).beginning_of_year}
But select method takes every object in memory before returning final result. Hence I will advise to use normal where clause and instead of flip_date take dob (which is a column in database) in consideration.
Like this
new_kids = Kid.where(discharge_date: nil).where('dob > ?', <date criteria>)
The select method (http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/select) works great if you are okay with the return being an Array.
I am still looking for a way to do this with an ActiveRecord_Relation return.
If others know how to do this, it would be much appreciated if you can share.
This example doesn't respond to your specific code, but to the extent it helps someone else with a similar question, here's a very simple example of how .select can be really handy:
#expired_memberships = User.select{|u| u.membership_expired_yesterday?}
In that example you've looped through all your Users and filtered them based on a custom method you defined on the User model (membership_expired_yesterday?). Now you can easily do stuff with that collection like this example in a mailer:
#expirations.each do |user|
MembershipExpirationMailer.with(user: user).first_reminder.deliver_now
end

How to define a Form Override for a Chained Form Field in Active Scaffold

Below example is taken from this documentation page:
https://github.com/activescaffold/active_scaffold/wiki/Chaining-Form-Fields
[Example start]
You can set an array of columns to update multiple columns when a column changes, and chain column updates:
class UsersController < ApplicationController
active_scaffold do |config|
config.columns[:author].form_ui = :select
config.columns[:author].update_columns = [:book, :editorial]
config.columns[:book].form_ui = :select
config.columns[:book].update_columns = :format
end
end
In this example, fields for book, editorial and format are updated when author changes, and when book changes only format is updated. A form override which use the new author or book must be defined for editorial and format columns, in other case those fields won’t change when they will be rendered again.
[Example end]
In the example it states "a form override which use the new author or book must be defined".
Question is how to define those form overrides ??
I have read the documentation on https://github.com/activescaffold/active_scaffold/wiki/Form-Overrides, and tried different form overrides, but with no luck so far, i.e. the columns are not being rendered again.
If you can help me with the code for those form overrides needed in the given example, then I should be able to port that to my code.
Here is the solution to my problem:
I followed the example on "https://github.com/activescaffold/active_scaffold/wiki/Chaining-Form-Fields", but when it did not work for my chained columns (when updating the first column all chained columns updates correctly, but when updating the second column then its chained columns renders to blank lists), then I focused (blindly?) on the details explained just below the example as I thought this was the first step to solve my problem: "A form override which use the new author or book must be defined for editorial and format columns, in other case those fields won’t change when they will be rendered again".
This was however not the case, no form override in the helper was needed to get this to work, in the helper the "options_for_association_conditions" is enough. As the example is for v2.4, maybe the form override is not needed anymore in v3.0+.
The solution is in the next paragraph on the example wiki: "Usually only the value of the changed column is sent, if you need another values to render the updated columns, enable send_form_on_update_column and all the form will be sent". My problem was, that the columns which was chained from the second column needed the value from the first column also, so setting up the second column with "send_form_on_update_column" (i.e. sending the whole form, not just its own value) solved my problem.
In the example this would be:
config.columns[:book].send_form_on_update_column = true

Resources