Grails Indexing - grails

How does Grails handle indexing in the database? I feel like if I try to do something like Person.findByName("KPthunder") it is going to have to search through all the records given that there is no index on the name field.
Do we have to add indexes to the columns we want to search through after grails makes the database?
All my searches are turning up are things about Grails index actions on controllers (including a search through my PDF copy of "Grails: A Quick Start Guide." I feel like I am overlooking something incredibly simple here...

Yes, we need to add indexes explicitly. They will definitely be used by DBMS, when appropriate.

Related

ActiveRecord: Search multiple models for a list of words

I have a search controller where I want to search a number of different models.
So say I have this query: "Foo bar baz". Then I want to have the following queries:
Model1.where("name like '%foo%' or name like '%bar%' or name like '%baz'").offset(o).limit(l)
Model2.where("title like '%foo%' or title like '%bar%' or title like '%baz'").offset(o).limit(l)
Model3.joins(:sources).where("sources.name" => [source1, source2]).where("name like '%foo%' or name like '%bar%' or name like '%baz'").offset(o).limit(l)
Most important is that I want to do it safe (no SQL injections) but it would be nice if I could keep it DRY and pretty as well. I am using Rails 4 but I am very new to it. I have seen that there's something called "Concerns" which may be something to use?
Thanks!
Dependencies
You'll probably be best using one of the search extensions for Ruby stacks:
Sunspot Solr
ElasticSearch
Sphynx
As a disclaimer, I've never used any of these in production, but from my understanding, each of them will "index" data in your application, and then perform a search based on that indexed data
--
Indexing
The bottom line is if you want to search multiple models, you'll be best harnessing an index-based search system. This will take all the data you want to index, and put it into a manageable, searchable format that you can then call when you need.
As far as I know, sunspot works very well in this regard (indexing your data). The trick is to include all your models in the Sunspot settings, from which you can then pull the data you need.
There's a great Railscast about this here:
I don't have any live code for you I'm afraid - if you need more ideas, though, I'll gladly come back with them

reviewing the fields I have in a model in rails

It seems like a silly question, but anyway:
I have a model with lets say 10-12 fields (columns) added in different migrations.
When I write code now (model, view, tests) I want to have a list of the column names.
Is there a good way to do so? (other than going to the DB manually and getting the column names)
It seems like an action the developer does quite often, or is it just me
Simply use ActiveRecord::Base#column_names:
Model.column_names
You could do something like:
ModelName.new.attributes.keys

Thinking Sphinx - Already have a search method in the model?

I'd like to use Thinking Sphinx, but I keep having problems because I have a very large rails project and the search method is used in many of my models. These already existing search methods conflict with Thinking Sphinx's search method. Is there any way around this?
I'm talking thousands of lines of code I would have to change if I had to change my search method to something else. I can't seem to find a way to change the default search method in Thinking Sphinx though either.
Thanks.
Just answered this on the TS list, but happy to answer here as well :)
There isn't any inbuilt way to do this, but in theory it could be possible. Firstly - Thinking Sphinx adds the class-level search method when you call define_index on a model - so, if you define your own search method after that, it'll overwrite the Thinking Sphinx version.
This means you could just define a new method that does the same thing - here's the code for Model.search:
def self.search(*args)
ThinkingSphinx::Search.new *search_options(args)
end
Which you could easily rename to something else:
def self.sphinx_search(*args)
ThinkingSphinx::Search.new *search_options(args)
end
The one possible catch with this is that Thinking Sphinx may have expectations internally on the search method existing and behaving as normal. I'm not sure - but give this a spin and see how you go!
Update:
As it turns out, the above suggestion doesn't cover all situations and it's still buggy. So, I think the fallback solution is to fork Thinking Sphinx, change the method names, and use your version instead of the canonical one.

rails lazy load of model attributes

Normally rails loads data with a :select => "*" from the database. I know I could change this. But I'd like to go another way: always only select "id" and load the attributes automatically later on when they are needed.
Example:
accessing user.description should if it's been loaded yet. if not, trigger a "SELECT description FROM users WHERE id=#{self.id}" and set it.
Anyone know if there's a rails plugin which does this? Or how to implement it?
Thanks,
Corin
I wrote a Rails plugins that does exactly this lazy_columns. Notice that a much better approach is to create a new model with the big columns you want to load on demand (since Rails load related objects lazily by default).
A quick google search turned up this, but I'm with glongman. I can't imagine what kind of performance issue would require this...
It is wise to just refactor your main "huge blob" fields into a separate model (like BookBody) which is usually not needed when operating with models in bulk. Alternatively, you can use the :select option on finders
BookWithHugeBlobOfText.find(:first, :select=>"only,small,columns")
Records selected that way will be readonly since the Rails philosophy says (and rightfully so!) that you need to have all data on the model to validate it. Lazy loading would be a nice to have, but as it stands now I would discourage you from using monkeypatch plugins for this.
Another option would be to create a SQL view which would only contain the lightweight fields and run your ops from there.

Best Way of Having End User Specify Sort Order in Rails

I am looking for a suggestion on the best way of having an end user from a Rails application's view files set the sort order of a result set returned by a model's "find" method. In other words I would like a user to be able to choose their sort order from a selection list.
Initially, I thought I could just put the string that I would put in the :order parameter, but that seems like a bad idea from a security point of view.
I suppose I could always use a switch based off values from a selection list, but that seems a bit bulky.
Thanks for looking.
I would use AR::Base#column_names to sanitise the input. Something like:
#models = Model.find(:all, :order => params[:sort].select({|name| Model.column_names.include? (name) } ).join(',') )
You can extend this, with a little pre-processing, to vary whether you want to sort ascending or descending with each key. Hope this helps!
This might be outside of what you're looking for, but lately, I've been relying on javascript to take care of the subsequent sorting for me. A good table sorter for prototype is Tablekit (http://www.millstream.com.au/view/code/tablekit), it's unobtrusive, fast, and easy to use. It also includes niceties like editing in place and column resizing.
something rails could copy from cakephp scaffold (paginator sorter on index() in cakephp)

Resources