Database with names


5 May 2005 @ 14:25

working with ajax and Ruby on Rails


the project where I use this codes can be seen on this address: http://1001line.dk/navne

The data
navne_controller.rb
CREATE TABLE `child_names` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(100) NOT NULL default '',
`sex` tinyint(4) NOT NULL default '0',
PRIMARY KEY (`id`),
FULLTEXT KEY `name` (`name`)
) TYPE=MyISAM AUTO_INCREMENT=7000 ;

Getting the names from this page was easy with a littel scripting and some hand work. I set up a web interface and and pasted the names from each letter section, and then i paresed the names.

def parsenames
@names = @params['navne']['navne'].split(",")
@sex = @params['navne']['sex'].to_i

@names.each do |navn|
a = ChildName.new
a.sex = @sex
a.name = navn
a.save
end
render_text @names.to_s + @params['navne']['sex']
end

As always when i do something with Ruby On Rails i find myself spending very little time on the data an code layer an almost all the time on the presentation layer, working with javascript and css.
And even the javascript part with the new javascript helpers have become mutch more easy when working with ajax or remote scripting

There is 3 functions in the web application. You can do fulltext search. You can get 10 ramdom names, boy or girl, and you can get a list of all the names stating with a paticular name.

I want to do the application with ajax so i went to se how in the weblog typo where there is a nice live search function, that I could learn from.


The controller
navne_controller.rb
class NavneController < ApplicationController
def index
end

def search
@search = @request.raw_post
@names = ChildName.search(@search)
render_without_layout
end

def random
@sex = @params["sex"]
@random_names = ChildName.random(10,@sex )
render_without_layout
end

def letters
char = @params["char"]
sex = @params["sex"]

@names = ChildName.letters(char,sex)
render_without_layout
end


The model
child_name.rb
class ChildName < ActiveRecord::Base

def self.search(query)
if !query.to_s.strip.empty?
ChildName.find_by_sql("SELECT * FROM child_names WHERE LOWER(name) LIKE '%#{query.downcase}%' ORDER BY name LIMIT 50")
else
[]
end
end

def self.random(amount, sex)

count = ChildName.count_by_sql("SELECT count(*) FROM child_names WHERE sex = #{sex}")
names = Array.new()
amount.times do
names << ChildName.find(:first, :conditions => [ "sex = ?", sex], :offset => rand(count), :limit => 1).name
end
names
end

def self.letters(char,sex)
ChildName.find(:all,:conditions => "name LIKE '%#{char}%' AND sex = #{sex}", :order => "name")
end
end

I was not to proud of the letters function. I wanted to do a find with the condititons - name LIKE '#{char}%' . But doing that did not work. I only got 2 or 3 posts. So i did LIKE '%#{char}%' witch resultet in a mutch to big resultset for every search, but then I could filter it out in the view-page.

The view
index.rhtml
    <div id="random_results">
    </div>
    <%= form_remote_tag :update => 'random_results',
        :loading => "Toggle.display('random_spinner')",
            :complete => "Toggle.display('random_spinner')",
          :url => { :controller => "navne", :action => "random" }
       %>
    <%= image_tag "spinner.gif", :id => 'random_spinner', :style => 'display:none;' %>
    <label for="boy">Dreng:</label>
    <input type="radio" name="sex" value="1" id="boy" checked="checked">
    <label for="girl">Pige:</label>
    <input type="radio" name="sex" value="2" id="girl" >
    <input type="submit" value="10 tilfældige navne">          
    </form>

All the ajax functions are done in the same way. I place a form_remote_tag in the view pages.
<div id="random_results">  </div> is going to coing to hold the contents from the name_controller method random.

The rest of the project i is about javascript and css

But first i will mention a little JavaScript i used to work around the form_remote_tag.

self.onload = function() {return document.forms[0].onsubmit();}
I wanted the random names to show up on the page from the start.
I could not do render_partial because random.rhtml is not a partial.
so to do it with Javascript is an easy way. The script also show a way to work in general with the ajaxing methodes i Ruby On Rails.


I used a lot of JavaScript and stylesheets to make the list for the letters. Lists is the best way to express list of links or menus with HTML, and is very easy to work with, if you know how ;-) . If You dont, then read Suckerfish Dropdowns


Valid XHTML 1.0!