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

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.

Related

Rails, mutiple create methods in one controller?

I need to have two (or maybe even more) different create (and update) methods in one controller. I already have views displaying the forms, so I basicaly only need to tell the submit which method to call in the controller. Is that possible? If so, how? Or can I only have one create method and have that method do different things depending on which view called the method?
Thanks
Ignoring the fact that this sounds like a really terrible idea, it's possible. You will need to add some more routes that will match the new actions in your controller. You won't be able to call them 'create' and 'update' because method names must be unique within the same class.
Having said that, I really beg you to rethink your approach. REST, as described in the Rails Getting Started guide, by far the standard for building Rails applications. If you're not familiar with it, I would recommend stopping where you are and reading up on it. Your application will be much easier to build and maintain, and you won't waste time asking structural questions. If you are familiar with it and are choosing to ignore it, then I wish you the best of luck.
you can use this command:
rails g scaffold_controller 'controller_name'
or if spastic method you can use this:
rails generate controller 'controller_name' add new
Let's say that you have an object Book. You can change values of Book in any method inside of your books_controller.rb as long as that method has access to #book.id.
def crazy_create_method
book.create (book_params)
book.save
end
That being said, try to stick to the default new/create methods and if you need to get weird later on it's always easy to call the code belong in whatever method you need. Rails bakes a lot of out of the box functionality into the default REST actions.
book.title = my_title
book.save

Rails fixtures or similar for creating data within an app

I want to populate a preferences table when a user is created. I can make a lash up version within the controller easily enough but would like something neater.
Can one do the same sort of thing with fixtures within a running application? If so how?
You could search for a gem. I've used https://github.com/FooBarWidget/default_value_for some time ago for a similar thing. It's a nice and clean solution.
In the end I simple defined an array in the model and array.each -ed it. Not perhaps the most elegant but still have all the values in one place for editing.

Performance differences between '.find' and '.where' methods

I am using Ruby on Rails 3.0.7 and I would like to know, regarding performance matters, what are differences between the User.find(<id>) method and the User.where(:id => <id>) method.
Under the hood, find does more or less what you're describing with your where. You can find the details in this post. That being said, if you're looking to grab a single record by id, then you might want to use find_one. That's what find winds up doing when you call it with a single argument of an id, but you'll skip past all the other code it needs to run to figure out that's what you wanted.
Short answer, but: It really doesn't matter (unless you don't have a unique-constraint on your id column).

Grails Indexing

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.

Passing parameters as path variables in ruby on rails

I'm still new to ROR, so pardon the simplicity of the question...
So http://www.example.com/controller/:id displays a record in my table, with :id being a number (1,2,3 etc.).
Is there a way I can have :id in the URL be the value of a field in the displayed record? Such that I can have http://www.example.com/controller/record_field? I want to have a human-friendly reference to specific records in my table. I'm sure this must be possible. Do I change something in routes.rb?
Thanks for the help!
The cleanest way is to add a new find method in your model (or simply use the find_by_fieldname Rails gives you in your control). Then you'll have your controller use that method instead of the regular find(params[:id]) to pull your model record.
Check out Ryan B's screencast on this here. It's pretty easy, and he's a good teacher, so you shouldn't have any problems.
I use the excellent rails plugin named friendly_id.
http://github.com/norman/friendly_id/tree/master
That should sort you out nicely. It is well documented too.
Take care around fields that might have modern Greek characters—might need to figure a work around for those.
Jon Smock's solution will work, too. I tend to prefer the following.
class Hamburger << ActiveRecord::Base
#this normally defaults to id
def to_param
name
end
end
class SomeModelController << ApplicationController
def show
#hamburger = Hamburger.find(params[:id]) #still default code
end
end
#goes in some view
This is the <%= link_to "tastiest hamburger ever", url_for(#hamburger) %>.
This is, loosely speaking, an SEO technique (beautiful URLs are also user-friendly and I suggest them to absolutely everyone even if you don't care about SEO, for example on pages behind a login). I have a more extended discussion of Rails SEO, which includes other tips like this, here.
Important tip: You should consider, at design-time, what you are going to do if the param should change. For example, in my hamburger scenario, it is entirely possible that I might rename "Sinfully Delicious Cheeseburger" to "Triple Bypass". If that changes URLs, there are some possible implications, such as breakage of customer links to my website. Accordingly, for production use I usually give these models an immutable permalink attribute which I initialize to be human-meaningful exactly once. If the object later changes, oh well, the URL stays the same. (There are other solutions -- that is just the easiest one.)

Resources