a hands-on tutoring needed

dear each, and all and others,

being a completeest newbie to RoR and having got dumb by a month or so
of googling how to add search faculty to a web app, I ask you for
help.

All I got is a database of 200 records so there is no need for sphinxes,
sunspots, elasticsearches, searchlogics, ferrets and other highly
esteemed and advanced engines and plugins. Thank you, sir. No.

I humbly ask for a list of files (and their contents) to be added to a
new app for user to get/see table of rows after s/he fills
text_tag_field and clicks submit button.

Don't send me to RailsEpisodes, please, I've sifted them with tons of
other crap.

yours,
sehrguey

Hi Sehrguey,

dear each, and all and others,

being a completeest newbie to RoR and having got dumb by a month or so
of googling how to add search faculty to a web app, I ask you for
help.

All I got is a database of 200 records so there is no need for sphinxes,
sunspots, elasticsearches, searchlogics, ferrets and other highly
esteemed and advanced engines and plugins. Thank you, sir. No.

I humbly ask for a list of files (and their contents) to be added to a
new app for user to get/see table of rows after s/he fills
text_tag_field and clicks submit button.

I built something like this as my first paying Rails job, a couple summers ago. I used Paperclip to store the external files in my mode, so to get the content of the text files (in my case, they were PDFs), I used a custom Paperclip processor (based on the Thumbnail processor that comes with Paperclip) to pipe the content of each uploaded file through the venerable pdftotext Unix command. https://gist.github.com/3028403

The results were not good enough to show the world (layout was destroyed) but the text content was extracted into a plain_text attribute on my model, and that's what I searched within.

The very simplest search technique of all is the substring match. This ignores dozens of years of search technology to simply answer the question "is this string present anywhere within that string?" In SQL, it looks like this: "SELECT * FROM `foos` WHERE `bar` LIKE '%baz%'. In Rails 3+, you would write this in your controller like this:

  @foos = Foo.where(["bar LIKE '%?%'",params[:q]])

Hope that's enough to get you started. There's also a number of Railscast episodes about this, starting with this humble substring match, and enumerating some simple Gems that can remove the grunt-work for you, like MetaSearch.

Walter

Hello Bill,

sometime ago I hacked the database structure from Kevin Yank's tutorial
“Build Your Own Database Driven Website Using PHP & MySQL” to use it for
a database at my site and it works OK storing and delivering a hundred
plus of records in the database I needed.

However I haven't deployed it, because of the rumors about the Glossy
Shining Kingdom of RoR that made me wade through a couple of startup
tutorials and Hurtl's Book.

I liked the RoR way but all the tuts I found were about blogs and
cookbooks and twitter-like apps without search funtionality.
How to add this feature to a basic RoR app after generating a model?

Yours`

sehrguey

dear Walter,

thank you for your kind attention and readiness to help.

You talked about my controller and proposed an awesomely nice line:

@foos = Foo.where(["bar LIKE '%?%'",params[:q]])”

Unfortunately, it is not enough to get me started because I can't
imagine where on earth to stick it into my controller that runs as
follows:

"class DisksController < ApplicationController
  # GET /disks
  # GET /disks.json
  def index
    @disks = Disk.search(params[:search])

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @disks }
    end
  end

  # GET /disks/1
  # GET /disks/1.json
  def show
    @disk = Disk.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @disk }
    end
  end

  # GET /disks/new
  # GET /disks/new.json
  def new
    @disk = Disk.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @disk }
    end
  end

  # GET /disks/1/edit
  def edit
    @disk = Disk.find(params[:id])
  end

  # POST /disks
  # POST /disks.json
  def create
    @disk = Disk.new(params[:disk])

    respond_to do |format|
      if @disk.save
        format.html { redirect_to @disk, notice: 'Disk was successfully
created.' }
        format.json { render json: @disk, status: :created, location:
@disk }
      else
        format.html { render action: "new" }
        format.json { render json: @disk.errors, status:
:unprocessable_entity }
      end
    end
  end

  # PUT /disks/1
  # PUT /disks/1.json
  def update
    @disk = Disk.find(params[:id])

    respond_to do |format|
      if @disk.update_attributes(params[:disk])
        format.html { redirect_to @disk, notice: 'Disk was successfully
updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @disk.errors, status:
:unprocessable_entity }
      end
    end
  end

  # DELETE /disks/1
  # DELETE /disks/1.json
  def destroy
    @disk = Disk.find(params[:id])
    @disk.destroy

    respond_to do |format|
      format.html { redirect_to disks_url }
      format.json { head :no_content }
    end
  end
end"

yours`
sehrguey

dear Walter,

thank you for your kind attention and readiness to help.

You talked about my controller and proposed an awesomely nice line:

@foos = Foo.where(["bar LIKE '%?%'",params[:q]])”

Unfortunately, it is not enough to get me started because I can't
imagine where on earth to stick it into my controller that runs as
follows:

"class DisksController < ApplicationController
# GET /disks
# GET /disks.json
def index
   @disks = Disk.search(params[:search])

The preceding line is already what I described. You have defined a self.search method in your disk.rb file (or else this line wouldn't work). That seems like you've already got the basics of a search function ready to go. Can I see the content of disk.rb?

Walter

Did you watch this one

http://railscasts.com/episodes/111-advanced-search-form

for a search without plugins, I think it covers well the basics of the subject to let you improve it.

this is the “advanced search form” episode.

If you were to find yourself a bit lost, there is a “simple search form one”

http://railscasts.com/episodes/37-simple-search-form

(those are old episode in rails 1 or rails 2, so there is a little bit of transcription to make, but it should be pretty easy to follow still)

Walter,
here is the contents of my disk.rb

dear Gregory,

I watched both episodes you mentioned, they did not work for me, I
couldn't figure out where the views come into play, which model stores
the searched items and what is in the controller of that invisible
model.

yours`
sehrguey

Walter,
here is the contents of my disk.rb
-----------
class Disk < ActiveRecord::Base
attr_accessible :director, :language, :notes, :starring, :title,
:volume_name, :wrapper

def self.search(search)
   if search
     find(:all, :condition=>['name LIKE ?', "%#{search}%"])
   else
     find(:all)
   end
end
end
------------

This is putting the search method where it belongs, in the model, rather than inline in the controller, as I had it. Completely identical in every functional way, just better MVC layout this way. So the only other question here is, do you have a form on your index page layout that can set a params[:search] with the desired search term? If you've looked at the RailsCast, there's a nice easy snippet there to make it with the form_tag helper (useful because you don't have an associated model). Can you show that code here?

You want to issue a GET request from the form to the index method, and then this will all just work. Your self.search method will default to gathering all records, because the query is 'WHERE name LIKE "%%"', which matches everything in the table. When you do pass a querystring to it that's like ?search=foo, then you will get the records where name contains foo. This means that there's no need for an additional controller method or a separate route or template for search results. If you do want to specialize the results page, you could do something in the index.html.erb template to switch on the presence of a params[:search] variable, and use that to change the page title or header or both.

Walter

Hi Walter,

there is form_tag in the index view`

Make that :conditions rather than :condition, and you're done.

Walter

thank you, Walter,

it worked after I had corrected the shameful typo and replaced 'name'
with 'title'further along the line.

I feel embarrassed and obliged or, maybe, vice verse.

gratefully yours`

sehrguey

happy moments are too short...

the search form worked and still works but it has a major flaw - when
the text_field_tag is left blank then all the db raws pop up on hitting
submit button.
How to prevent it?

I tried to substitute 'if (search.present?)' for just 'if search' in
disk.rb (the googled out trick seemed so logical) yet it availed of
nothing and all the records were displayed again.

Now what?

yours`
sehrguey

This is why you are getting all the records, if there’s no “search” then it will find all the records.

else

  find(:all)
end

You can send an empty array or whatever you want, or maybe you can handle that in the controller

Javier Q.

Your controller is using this method to load results on your index page, whether or not any search was performed. So it's perfectly reasonable for the empty search to return all results.

  def self.search(search)
   if search
     find(:all, :conditions=>['name LIKE ?', "%#{search}%"])
   else
     find(:all)
   end
end
end

  def index
   @disks = Disk.search(params[:search]) # <-- right here

   respond_to do |format|
     format.html # index.html.erb
     format.json { render json: @disks }
   end
end

If you kink the self.search method to only return results if there is a non-empty search request, then you will never see anything on your normal index view unless a search request has been entered.

You could kink the form to only submit if there is a value in the search field, you would do that with JavaScript. Something like this (inline) or better you would use Prototype or jQuery to write an unobtrusive handler.

<%= form_tag disks_path, :method => 'get', :onsubmit => "return (this.search.value != '')" do %>

Walter

Javier Quarite wrote in post #1067748:

You can send an empty array or whatever you want, or maybe you can
handle
that in the controller

Walter Davis wrote:

You could kink the form to only submit if there is a value in the search
field, you would do that with JavaScript. Something like this (inline)
or better you would use Prototype or jQuery to write an unobtrusive
handler.

O weh, dear sirs,

If I could I would but before I should know the way to. Presently I
consider your enlightened talk with awe like some heaven dwellers'
parlance incomprehensible for mere mortals.
OK. I asked Google about sending arrays in rails and got another bowl of
geek-talk and changed 'else find(:all)' to whatever I wanted just to be
punished for transgressions of convention over configuration.
Then I added unobtrusive addition to form_tag which seasoning brought no
changes to conventional displaying of everything not searched for.

Of course, RoR has means and ways to solve a petty problem like this
one. The only queston is` 'where to discover?'

yours`
sehrguey

I would start by working right through some good Ruby tutorials (to
understand the language better) and also through some good Rails
tutorials (railstutorial.org is good and is free to use online) to
understand the Rails magic. Take a week out to do that and then you
should be good to tackle a multitude of problems.

Also monitor this list. Any time that you understand the question
then follow the replies and attempt to understand the answers. That
way you will learn a lot. In no time you will find yourself answering
questions.

Colin

Colin Law wrote in post #1067862:

I would start by working right through some good Ruby tutorials (to
understand the language better) and also through some good Rails
tutorials (railstutorial.org is good and is free to use online) to
understand the Rails magic.

thank you Colin,

you are right railstutorial.org is outright good and I did all of it.
Unfortunately, it has no search form whatsoever. Neither do intensely
good tutorials at guides.rubyonrails.org/getting_started.html

That's why I knocked at this here forum asking for help of those who
understand the language and the Rails better.

yours`
sehrguey