Skip to content
Jun 17 09

RoR Restful Authentication

by admin

I got sick of forgetting what to google to find this so I am keeping my notes here.

./script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication

Then run

./script/generate authenticated user sessions

You can add --include-activation to have add more features but i havent used that yet…. It works great as is.

Jun 9 09

Re-compiling PHP 5 for OS X

by admin

This post is intended as a simple reminder for me to help me remember what I did when setting up a new PHP environment… help yourself to my notes, but you’re on your own if it breaks your server.

Here is a breakdown of what to install in what order… jpeg6, gd, libpng, mcrypt, mhash

Build the jpeg6 lib first- ftp://ftp.uu.net/graphics/jpeg/

I put the tar files in ~/_bin then I unpacked it with

tar -zxf [tarfile]

then moved the dir to /usr/local/php. Then CD into that dir and do the following:

cp /usr/share/libtool/config.sub .
cp /usr/share/libtool/config.guess .
./configure --enable-shared
make
sudo make install

Then you should recompile GD so it will see the new jpg6. Same thing, download GD to the ~/bin and untar it and move the dir to /usr/local/php.

./configure

You should see something like this:

Support for PNG library:          yes
Support for JPEG library:         yes
Support for Freetype 2.x library: yes
Support for Fontconfig library:   yes
Support for Xpm library:          yes
Support for pthreads:             yes

Then do this:
make
sudo make install
l

Now you will need libpng (http://www.libpng.org/pub/png/libpng.html). Untar it and move it to /usr/local/php

./configure
make
sudo make install

Now you need freetype and xpm… Im not going to try and figure out fonts so since fonts are already on the system you can use them this way in the config for php in just a few minutes.

–with-freetype-dir=/usr/X11R6 \
–with-xpm-dir=/usr/X11R6 \

Now for mcrypt and mhash. Go here and download the latest version of mcrypt ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/libmcrypt/.  Same as the others, untar them and move them to /usr/local/php. CD into that dir then

./configure
make
sudo make install

And finally mhash. Go here and download it. http://sourceforge.net/project/showfiles.php?group_id=4286. Again, untar it and move it to /usr/local/php then

./configure
make
sudo make install

Now you are finally ready to compile PHP.

./configure --with-prefix=/usr \
--with-mandir=/usr/share/man \
--with-infodir=/usr/share/info \
--with-disable-dependency-tracking \
--with-apxs2=/usr/sbin/apxs \
--with-ldap=/usr \
--with-kerberos=/usr \
--with-enable-cli \
--with-gd \
--with-freetype-dir=/usr/X11R6 \
--with-xpm-dir=/usr/X11R6 \
--with-png-dir=/usr/local/lib \
--with-jpeg-dir=/usr/local/bin \
--with-tiff-dir=/usr \
--with-zlib-dir=/usr \
--with-enable-trans-sid \
--with-xml \
--with-enable-exif \
--with-enable-ftp \
--with-enable-mbstring \
--with-enable-mbregex \
--with-enable-dbx \
--with-enable-dbase \
--with-enable-trans-sid \
--with-enable-sockets \
--with-enable-wddx \
--with-enable-bcmath \
--with-iodbc=/usr \
--with-curl=/usr \
--with-config-file-path=/etc \
--with-sysconfdir=/private/etc \
--with-mysqli=/usr/local/mysql/bin/mysql_config \
--with-mysql=/usr/local/mysql \
--with-pdo_mysql=/usr/local/mysql \
--with-openssl \
--with-xmlrpc \
--with-xsl=/usr \
--with-mcal=/usr/local/php \
--with-mcrypt=/usr/local/lib \
--with-mhash=/usr/local/lib \
--with-mime-magic \
--with-pear

I was able to run make fine, but when running make test I got an error…. After alot of digging around, I found this helpful post at php.net.

“After screwing around for an hour and screaming many profanities at my computer I looked back at the error and noticed:

/usr/local/mysql/lib/<b>mysql/</b>libmysqlclient.15.dylib

Why it was using this path I do not know, but I headslapped when I realised how simple it was! I solved the problem by creating a link called mysql that linked back on itself:

cd /usr/local/mysql/lib
sudo ln -s ./ mysql

Problem solved! I probably should have figured out why it was doing this instead, but this was easier and saved me from allot more frustration.”

This worked for me as well.

Nov 25 08

Reindexing Ferret Part II

by admin

Automating the re-indexing process was a bit different than I thought it would be.

Yesterday I posted that you can use script/console. Which is true, but you cant run that in a cronjob. Or, at least I couldnt get it to run in a cronjob.

So I learned about script/runner. I used it like this… I put a .rb script in lib/task called ferret_index.rb.

class FerretIndex < ActiveRecord::Base
MyModel.rebuild_index
end

Then my cronjob

0 1 * * 7 /usr/local/bin/ruby /usr/local/apache2/htdocs/<my project>/script/runner /usr/local/apache2/<my project>/lib/task/ferret_index.rb

Every sunday at 1:00 am my index will be updated.

Nov 24 08

Reindexing Ferret

by admin

Its really simple, wished I had seen this part of the documentation a couple months ago.

Lesson learned. As the databse was being updated more often and becoming very large, indexing became more difficult to do just by doing a search in the browser. Back to the documentation and there it was.

script/console

>>MyModel.rebuild_index

Plus, the indexing seems to be much faster. Looking into  running the DRb server. Im worried about taking a performance hit. I’ll post what I learn when I try it out

Sep 28 08

Green River

by admin

CottonwoodNo place I would rather be.

I had a chance to escape to the Rio Verde for a couple of days. Fishing was fair… not slow, not fast. The Rainbows were really active on San Juan worms. Browns were looking at zebra midges and hoppers and PMX’s.

I can’t get enough time on the Green. Hope to go back soon.

Aug 30 08

Multiple Effect.toggle

by admin

I couldn’t find a clear example on how to handle a blind down and a update with the same onlick event.

Here is what i came up with… im pretty sure there is a better way to do this but this worked just fine.

<span id=”group1_minus” style=”display:none;”><img src=”/images/buttons/small_minus.gif”></span>
<span id=”group1_plus” ><img src=”/images/buttons/small_plus.gif”></span>

<a href=”#” onclick=”Effect.toggle(’blinddown_group1′, ‘blind’, {duration: 0.5}); new Ajax.Updater(’tester’, ‘group1_swap’, {asynchronous:true, evalScripts:true});”>Group 1</a>
<div id=”blinddown_group1″ style=”display:none;”>

#cool stuff here

</div>

Then in the controller:

def group1_swap
render :update do |page|
page[:group1_minus].toggle
page[:group1_plus].toggle
end
end

This worked well for a side nav that needed to blind toggle and swap a +/- graphic to indicate if that section of the nav was open or closed. I havent tried it, but I imagine that you could do many Ajax Updaters in one onclick event.

Aug 20 08

Pagination with Ferret

by admin

I needed simple pagination for ferret search results that were for next page, previous page and go to page.

After working with a couple different pagination plugins i was able to get pagination kind of working. But my design requirements were a little more unique and i needed full controll of the output and view. Then on the ride home it hit me. It’s really simple. I need to take care of just a handfull of options. per_page, page and offset.

It begins by setting these options upstream in the controller:
(params[:p] is coming from the URL to tell me what page im on. If there is no params[:p] just set it to 1.)
if !params[:p]
params[:p] = 1
end

per_page = 50
page = params[:p].to_i    #to_i converts a string to a integer
offset = (per_page * page) – per_page

The ferret method is standard:
@results = MyModel.find_by_contents(search_string, :limit => per_page, :o ffset => offset)

Now i can control pagination controls like this:
@page_count = @results.total_hits
@current_page = page
@total_pages = @results.total_hits / per_page
@next_page = page + 1
@previous_page = page – 1

Thats it. Now on to the view.

To show Page 2 of 83 do this:
Page <%= @current_page %> of <%= @total_pages %>

To get next page do this:
<a href=”?p=<%= @next_page %>”>Next</a>

To get previous page do this:
<a href=”?p=<%= @previous_page %>”>Previous</a>

To give users the option to jump to a page do this:
Go to page <%= text_field_tag :p %>

Some things to look out for:
@results.total_hits can be a bit unreliable, making pagination unreliable. So far, it seems if the index is clean and not too “fancy” total_hits is pretty accurate. Im still not 100% clear on how to get indexing more reliable for total_hits.

Jul 25 08

Building site search with Ferret

by admin

I recently had the opportunity to build a search feature using the Ferret project.

So I wanted to document what I learned while it was still fresh in mind. First, getting Ferret and acts_as_ferret installed was pretty simple and straight forward. This blog post got me off to a good start.

The first index it created was ok but I was looking for more relevant results. The boost option made the difference I was looking for. Here is how I set it up in my model.

#use acts_as_ferret plug in to assist in creating the index
acts_as_ferret :fields => { :main_tags        => { :boost => 4, :store => :yes },
:description      => { :boost => 2 },
:keywords         => { :boost => 1, :store => :yes }, #have to add store => yes for lazy to work
:photo_code       => { :boost => 1 },
}

The production server has over 230k records in it. It took over 6 hours to index everything… (im still working out how to speed that up)… so for development I started with just a few hundred records. That only took a couple of minutes to index.

Once I had my index done I was ready to search it.

search_string = params[:search_term]

@results = Photo.find_by_contents(search_string, :limit => 50) #defaults to 10 results

(pagination notes are coming in a later post)

One of the unique requirements of this project was the need to refine the search on a specific set of keywords. For example, we need to know how many of the search results are also tagged with age, gender or ethnic keywords. So, to know how many of the search results are also tagged with “Mid Adult Women (2,544) ” I used the lazy method in ferret to spare a hit to the database for it. Going to the database for these refine search options put page loads over 10 seconds, 20+ seconds in some cases. Since that is completely unacceptable, Im glad the Ferret team came up with :lazy. It may have saved my job ;-)

Photo.find_by_contents(search_string + ” AND Mid Adult Women”, {:lazy => [:keywords]}).total_hits

I learned that find_by_contents will ignore the :condition option for extra query info. But, you can do multiple AND OR statements as part of the search string. Now I can refine my search many times over without ever touching the database!

In the end I am searching over 230k records getting as much as 20k results on some searches and showing total_hits on over 60 refine search options in less than .4 seconds with only one hit to the database. Pretty cool.

Next is pagination

Jul 1 08

Yellowstone

by admin

Yellowstone is one of my most favorite places!

img_0114.jpgJust got back from a 5 day vacation in YNP and surrounding areas. The kids did really good considering there was a lot of driving and sight seeing. One of the things that made it fun for the kids was that the park has a junior ranger program. They had to pass off a list of requirements that gave them a chance to learn some cool things about the park by themselves.

img_0102.jpgI had a couple brief oportunities to fish the Firehole. I managed a few small browns and rainbows on a soft-hackle. Also, I had the pleasure of interviewing Bob Jacklyn for my fly fishing podcast.

img_0180.jpgWe took a break from the park and drove to Ennis MT. Just outside of Ennis there is a small ghost town called Nevada City. If you go on a Saturday they have a full cast of characters that you can talk to. They talk and act just as if it was the 1860’s and you are some strange visitor from the future. All the characters were great with the kids and really made the history of they 1860’s come to life.

I can’t wait to go back this October.

Jun 18 08

Select country onchange update state

by admin

I found a lot of different post about this that i couldn’t get to work for me so, here is what i did to get it to work. I was reading on http://api.rubyonrails.org and found remote_function. It was easy from there.

My Controller:
def register
@user = User.new(params[:user])
if request.post? and @user.save
flash.now[:notice] = “User #{@user.username} created”
@user = User.new
end

### a bunch of other code here
@state = ”

end

def dynamic_states

@state = States.find(:all, :conditions => ["country_code = ?", params[:country_id]]).map {|u| [u.name, u.id]}

render :layout => ‘modal’ #just has yield tag in it

end
My Views:

dynamic_states.rhtml:

<%= select(:state, :id, @state) %>

register.rhtml

<select id=”country_id” name=”country_id” onchange=”<%= remote_function(:update => “state_id”,
:with => “‘country_id=’ + $(’country_id’).value”,
:url => { :action => ‘dynamic_states’ }) %>”>
<option>Choose a country</option>
<option value=”US”>United States</option>
<option value=”CA”>Canada</option>
</select>

<div id=”billing_state_id”>
<select>
<option>Choose a country first</option>
</select>
</div>