the project where I use this codes can be seen on this address: http://1001line.dk/navne
The data
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.
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
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<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();}