Archive forWeb Development

Installing MySQL on Snow Leopard

Just got my new MacPro this weekend. After installing my common applications, I had to install my develoment tools as well. These are the instructions to install MySQL 64-bit version on OS X Snow Leopard.

First of all, note that we are going to install MySQL compiling from source. So make sure you have installed Xcode tools and you know your way around Terminal ;)

Now lets set up our personal profile where we declare our path variable. Fire up Terminal and create/edit your profile file:

vi ~/.profile

Set your path variable like this:

export PATH="/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin:$PATH"

Close and save the file. Now load the the path variable to your current shell:

source ~/.profile

Now verify your updated path:

echo $PATH

You should see /usr/local/bin at the beginning of the line returned by the system.

Now lets download the MySQL source and start compiling like crazy :

curl -0 http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.41.tar.gz/from/http://mysql.easynet.be/
 
tar xzvf mysql-5.1.41.tar.gz
cd mysql-5.1.41
CC=gcc CFLAGS="-arch x86_64 -O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-arch x86_64 -O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-shared --with-plugins=myisam,innobase --with-zlib-dir=bundled --with-big-tables --with-readline
 
make
sudo make install
 
cd /usr/local/mysql
sudo ./bin/mysql_install_db --user=mysql
sudo chown -R mysql ./var

Ok, everything should be compiled and installed without problems. Now lets create the launch daemon with the following content

sudo vi /Library/LaunchDaemons/com.mysql.mysqld.plits
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>KeepAlive</key>
 <true/>
 <key>Label</key>
 <string>com.mysql.mysqld</string>
 <key>Program</key>
 <string>/usr/local/mysql/bin/mysqld_safe</string>
 <key>RunAtLoad</key>
 <true/>
 <key>UserName</key>
 <string>mysql</string>
 <key>WorkingDirectory</key>
 <string>/usr/local/mysql</string>
</dict>
</plist>

Change the user to root.

sudo chown root /Library/LaunchDaemons/com.mysql.mysqld.plist

Now, to start / stop MySQL, run the these commands:

sudo launchctl load -w /Library/LaunchDaemons/com.mysql.mysqld.plist
 
sudo launchctl unload -w /Library/LaunchDaemons/com.mysql.mysqld.plist

Now the last thing todo is to set the root password:

mysqladmin -u root password "mypassword"

Now MySQL should be running smoothly and without problems on Snow Leopard.

NOTE: For the RoR mysql gem, use the following command:

sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-dir=/usr/local/mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config

Comments (3)

Mac Leopard, ROR 2.2 and MySQL

Finally, I found a nice solution for the RoR 2.2 MySQL problem. The initial problem was that the MySQL library isn’t bundled with RoR anymore, and you need to install it as a gem. No big deal at first, but we Leopard users are “plagued” with the fact that Apple has somewhat of an exotic installation method of web programming.

The stock MySQL and Apache are both 64bit, but the Ruby interpreter is 32 bit. That’s why you can’t use the 32 or 64 bit MySQL library gem. I found a lot of “idea’s” on the net, but none of them helped out, or I didn’t think they where good enough.

One of them was to run a second MySQL instance on 32bit. A lot of users solved  that way but I found it just stupid running 2 MySQL instances. So then it struck me, why not recompiling the stock MySQL as a universal build that supports both 32 and 64 bit?

So I did. I downloaded the source from the MySQL website and compiled it like this:

MACOSX_DEPLOYMENT_TARGET=10.5 \
CFLAGS='-O3 -fno-common -arch i386 -arch x86_64' \
LDFLAGS='-O3 -arch i386 -arch x86_64' \
CXXFLAGS='-O3 -fno-common -arch i386 -arch x86_64' \
./configure \
'--disable-dependency-tracking' \
'--prefix=/usr/local/mysql' \
'--localstatedir=/usr/local/mysql/data' \
'--libexecdir=/usr/local/mysql/bin' \
'--with-comment=MySQL Community Server (GPL)' \
'--enable-thread-safe-client' \
'--enable-local-infile' \
'--enable-shared' \
'--with-zlib-dir=bundled' \
'--with-big-tables' \
--with-readline \
'--without-docs' \
'--with-plugins=myisam,innobase'

And my problem was solved. I had one MySQL instance running, and I finally could use RoR 2.2.

Now the only problem remaining is getting PHP to run properly.

Comments

Mac, though love

I recently made the switch to mac. I just love working with it. But I’m experiencing some downsides to it. This is probably due to lack of knowledge about Mac.

Like most of you know, I’m in the web development business. So I need PHP and Ruby on Rails.

I was happy to notice that PHP en RoR where installed by default on Leopard. But then I needed MySQL PDO. Hmm, the default PHP installation doesn’t support MySQL PDO. So I need to recompile. So I downloaded the PHP source and tried to recompile it with almost the same parameters I found of my previous installation. But still no go. I just gave up at the moment.

Then next thing happend. RoR 2.2 came out. So I wanted to upgrade. I upgrade an old experimental app and tried to run it. Oops, looks like RoR doesn’t ship anymore with mysql library. After a quick google, I noticed I had to install the mysql 2.7 gem.

Ok, that’s easy. Tried to install it, but ran into errors. So after some more googling I saw that other mac users ran into the same problem and various solutions where found. But, none of them worked for me. Well, I didn’t tried them all. Some of the solutions mentioned installing both 64 and 32 bit version of MySQL. Well, I just like to run a clean system and not messing with diffrent installations.

I googled a lot lately but still didn’t found a solution for both of my problems. So if any of you readers might have found a solution to help me out, please do share.

Comments

Create sub folders in your Rails application

I got some nice emails conserning my restful search and the Object-oriented approach to ActiveRecord posts.

But a few of those mails had another thing in common. Some users find all the finder classes in the helper folder overwhelming, and they don’t like having them in the same folder as their view helpers.

Well, the thing you can do, is put all the finder classes in a subfolder. Lets call the subfolder “finders”, just for the fun of it :p.

Now Rails won’t load those finders anymore, since it won’t recognize your newly created subfolder. So open your environment.rb file and paste in the following code:

  Dir.glob("#{RAILS_ROOT}/app/helpers/*[^(.rb|.ignore)]").each{|dir| config.load_paths << dir }

This will tell Rails to load all files and folders in the helpers folder, that don't contain .rb or .ignore in its name.

So all the view helpers won't get loaded again, and if you have a subfolder that you don't need to be loaded anymore in your helpers folder, but still want the code, you can just rename the folder.

So I hope this might help you guys keeping your application clean. Offcoure you can also use this on other subfolders you might want to create ;)

Comments

RESTful search

During the development of my new project, I read a lot on the REST subject. In my opinion, it is a nice way of keeping your application clean and maintainable. But I stumbled upon a small problem when I had to implement a search for my resources.

In all the examples you find on the net, you will see how to create your basic CRUD actions in REST. So create, update and delete isn’t a problem at all. But when it came to implement a search system, you find nothing. Well, nothing is a big word, you do find posts, but all of them work diffrent.

The first thing I needed to do was to deside how I would handle the search. The first possibility is to create a new controller so it would fit in the REST filosophy. Just see the search as a resource. I didn’t realy feel right to see a search as a separate resource. I just see the search as a filter on an existing resource, so why defining the search as a resource of its own??

The next logical step was just adding a new action in my resource controller called search. But again, a new action just to search? Not a real good idea I think. Like I said before, a search is just a filter on your list, so I should be part of the index action.

So there we go. We just send our search parameters to the index action and filter our list there where it should happen.

If it was just as simple as that. You can’t just use a normal POST method form, becouse Rails will see that as create. And if I would use the GET method, all the search parameters would apear in the address bar. I know thats not a big of a deal, but I personaly think that isn’t realy clean.

But then it came to me. We live in an age where you can’t find an application without Ajax. So why not implement our search with Ajax? This way, we can send a GET request with our search parameters to the controller and rebuild our list without having to reload the hole page.

Some readers might think, building your search in the index action will make your index action look ugly. Well, for those readers, check out my previous post on building your query string dynamically in an object-oriented way with ActiveRecord.

As far as I know, this is the cleanest way to implement a search the RESTful way. But ofcourse, this is just my vision on the subject, and other developers will say you HAVE to create a separate controller. But if you think like me, and can’t comprehend why a search is a separate resource, my filosophy will be a nice way to follow.

If you have some input or improvements, please do share them :)

Comments (1)

REST design with extra actions

Yesterday, I had to add some extra actions in my controllers, so I could view some charts. The problem was that Rails didn’t recognize the actions, becouse Rails sees you action name as an id.

But Rails wouldn’t be Rails if it didn’t had a clever solution. Lets say you have a a resource called “Resource” and a similar controller. You want to add a new action and view to the resource controller named “charts” .

Just open your routes.rb file and find the line where you map the resource and add the following:

1
  map.resources :resource, :collection => [:charts], :member => [:print_pdf]

For the sake of being complete, if have added a member. The diffrence between a collection and a member is that collections work on all items of that resource (no id needed, like index action),
so:

1
  charts_resources_path()

could be used and give you a page with covering the charts of all resources

while a member works on a single item of the resource, defined by it’s id

1
print_pdf_resource_path(1234)

would print the resource with id 1234 as pdf

of course like with all other REST actions (or CRUD actions, to be correct) you can use additional named params like:

1
2
chart_resources_path(:type => :monthly)
print_pdf_resource_path(1234, :font => "Arial")

Comments

Object-oriented approach to ActiveRecord

One of my colleges (the main programmer for the company I work for) has created a nice post on creating dynamic search criteria in an object-oriented way using Rails ActiveRecord. You can find his post here.

At first, I was a little out of balance, becouse I couldn’t realy see the advantage of it. But now after working on a few big rails projects, I realized quickly that this was a real neat way of generating a query in ActiveRecord.  Yet, I had to make a few changes.

First, create a class called record_finder.rb and add the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class RecordFinder
 
  attr_reader :parameters
  attr_accessor :order_by 
 
  def initialize (bool_mode = 'AND')
    @bool_mode = bool_mode
    @sqls = []
    @parameters = []
    @includes = []
    @order_by = ''
  end
 
  def add (sql, *params)
    @sqls << sql
    @parameters += params
  end
 
  def add_ref(field, int)
    add "#{field.to_s} = ?", int
  end
 
  def add_wildcard(field, value)
    add "#{field.to_s} LIKE ?", "%#{value}%"
  end
 
  def add_range(field, range)
    if field.instance_of?(Hash)
      add "#{field['from']} >= ?", range['from']
      add "#{field['until']} <= ?", range['until']      
    else
      add "#{field} >= ?", range['from']
      add "#{field} <= ?", range['until']
    end      
  end
 
  def has_conditions?
    @sqls.filled?
  end
 
  def add_finder(finder)
    if finder.has_conditions?
      @sqls << finder.sql_string
      @parameters += finder.parameters
    end
  end
 
  def sql_string
    @sqls.collect{|sql| "(#{sql})"}.join(" #{@bool_mode} ")
  end
 
  def get
    if @sqls.length > 0
      [ sql_string ] + @parameters
    else
      nil
    end
  end
 
  def get_all
    options = {
      :include => @includes,
      :conditions => get,
    }
 
    if @order_by.filled?
       options[:order] = @order_by
    end
 
    return options
  end
 
  def include(path)
    unless @includes.include? path
      @includes << path
    end
  end
 
  def is_empty(var)
    return var == nil || var == ""
  end
end

The only special diffrence is the add_range action. With the add_range, you can search for a field in a sertain range. If the parameter is a Hash, you can use it to filter a record that has a start and end date. Otherwise, you just filter a range on one field.

The next step is to create a finder class that inherets from the RecordFinder class for all the resources you wish to search through. It might look like something as this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ResourceFinder < RecordFinder
  def by_user(user_id)
    add("user_id = ?", user_id)
  end
 
  def by_name(name)
    add_wildcard("name", name)
  end
 
  def read_search(search)
    if search
      self.by_name unless is_empty(search[:name])
    end
  end 
end

Now, you have 2 options on how to build your query. The first one is to call for all the actions needed in your controller like this:

1
2
3
4
5
  finder = ResourceFinder.new  
  finder.by_user(session[:user].id)
  finder.by_name(params[:search][:name])  
 
  @resource = Resource.find(:all, finder.get)

Now you build your search in your controller. But if you have a lot of search parameters, your index action could get ugly after a while. That’s why I have created the read_search action in my ResourceFinder.rb class. Just pass you search hash to it, and build your query in there. This way, you build-up is centered in the finder class and your controller stays neat and clean :)

Comments

Rails breadcrumbs

As I was working on my new project, I was in need of a some breadcrumbs to implement on my site. Since I hate doing the same task over and over again, I looked for a ready to deploy plugin. After some googling, I quicly realized that a standard way of creating breadcrumbs is virtualy impossible.

The way of creating your bread trail can depend on diffrent situations and can change from project to project. I just think that this way of generating your bread trail I realy neat, and would fit about 80% of most projects. The application controller code can even serve as a starting point for generating the trail dynamicaly.

Start and put the following in your application_controller.rb file:

 protected
   def add_breadcrumb name, url = ''
     @breadcrumbs ||= []
     url = eval(url) if url =~ /_path|_url/
     @breadcrumbs &lt;&lt; [name, url]
   end  
 
   def self.add_breadcrumb name, url, options = {}
     before_filter options do |controller|
       controller.send(:add_breadcrumb, name, url)
     end
   end

Theses methods will be used in other controllers to build up the trail. Offcourse, every trail starts with the Home page. So it would be stupid to repeat that in every controller. The author of the blog post suggested to put

add_breadcrumb 'Home', '/'

in the top of your application controller, but that gave some problems for me. So what I did is, since I use the initialize method in my application method, is just to put the code right there.

So how do you continue to build up the trail you might think now? Just open an arbitrary controller and add something similar to the top:

  add_breadcrumb 'Resource', '/resources'
  add_breadcrumb 'List', '', :only =&gt; [:index, :destroy]
  add_breadcrumb 'Create a new resource', '', :only =&gt; [:new, :create]
  add_breadcrumb 'Edit a resource', '', :only =&gt; [:edit, :update]

This way, all your crumb entries are grouped at the top of the controller. But if you need to customize, you can just add an entry in your action aswell.

Now, you would like to view your breadcrumbs. Go to the right view (most likely you default layout page) and add the following code:

<%= @breadcrumbs.map { |txt, path| "
  • #{link_to_unless(path.blank?, h(txt), path)}
  • " } %>

    Source: http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/

    Comments (2)

    Google Gears meets Ruby on Rails

    It has been a while since I posted something new. But I have a few articles in mind that I will post soon.

    The first one is something that I discovered a few days ago. The fantastic toolkit Google Gears that enables webapplications to work offline has met RoR.

    2 students, Michael Marcus and Rui Ma, have made it all possible. I haven’t had the time to play with it yet, but I’m working on a small project now that fits the need to experiment with.

    The things I can tell is that they wrote some sort of a wrapper that to work with all the javascript api’s that Gears has. Next to that wrapper, you still need some javascript to work within the browser, but the syntax looks very ruby-ish.

    Becouse crud-actions over http can be simulated, we can use the same views and controllers like we would use for a normal online application.

    The two students hope they can make it available as a plugin soon, so it can be used in existing projects.

    For more info, check out the Gears on Rails project page.

    Comments

    Firefox 3 out now!

    Jej, it is finally here. Firefox 3 is out. I was waiting a long time for this release. I dind’t use the beta or RC versions, so it was a bit hard to wait. But it was worth it. One of the main things I couldn’t wait for was the fact that FF 3 would consume less memory.

    Firefox 2 was consuming between 220.000 and 270.000k on my laptop. Now it only consumes between 40.000 and 70.000k. I haven’t take the time yet to test everything in detail.One thing I had problems with was Firebug. The 1.0.5 release doesn’t work under Firefox 3 and the getfirebug website is still down. But luckely I found a SVN build at MyZoneLabs that does the trick.

    So do not hesitate and GET FIREFOX 3.0 . Don’t forget, the Mozilla Foundation is trying to break the Guiness World Record of most downloaded software in one day. So if you stumble upon this post before 17:00 UTC on June 18, 2008 and downloaded Firefox, you are one of the many who is helping to acheeve this goal.

    Here is a changelog of FireFox 3.0

    More Secure

    • One-click site info: Click the site favicon in the location bar to see who owns the site and to check if your connection is protected from eavesdropping. Identity verification is prominently displayed and easier to understand. When a site uses Extended Validation (EV) SSL certificates, the site favicon button will turn green and show the name of the company you’re connected to. (Try it here!)
    • Malware Protection: malware protection warns users when they arrive at sites which are known to install viruses, spyware, trojans or other malware. (Try it here!)
    • New Web Forgery Protection page: the content of pages suspected as web forgeries is no longer shown. (Try it here!)
    • New SSL error pages: clearer and stricter error pages are used when Firefox encounters an invalid SSL certificate. (Try it here!)
    • Add-ons and Plugin version check: Firefox now automatically checks add-on and plugin versions and will disable older, insecure versions.
    • Secure add-on updates: to improve add-on update security, add-ons that provide updates in an insecure manner will be disabled.
    • Anti-virus integration: Firefox will inform anti-virus software when downloading executables.
    • Vista Parental Controls: Firefox now respects the Vista system-wide parental control setting for disabling file downloads.
    • Effective top-level domain (eTLD) service better restricts cookies and other restricted content to a single domain.
    • Better protection against cross-site JSON data leaks.

    Easier to Use

    • Easier password management: an information bar replaces the old password dialog so you can now save passwords after a successful login.
    • Simplified add-on installation: the add-ons whitelist has been removed making it possible to install extensions from third-party sites in fewer clicks.
    • New Download Manager: the revised download manager makes it much easier to locate downloaded files, and you can see and search on the name of the website where a file came from. Your active downloads and time remaining are always shown in the status bar as your files download.
    • Resumable downloading: users can now resume downloads after restarting the browser or resetting your network connection.
    • Full page zoom: from the View menu and via keyboard shortcuts, the new zooming feature lets you zoom in and out of entire pages, scaling the layout, text and images, or optionally only the text size. Your settings will be remembered whenever you return to the site.
    • Podcasts and Videocasts can be associated with your media playback tools.
    • Tab scrolling and quickmenu: tabs are easier to locate with the new tab scrolling and tab quickmenu.
    • Save what you were doing: Firefox will prompt users to save tabs on exit.
    • Optimized Open in Tabs behavior: opening a folder of bookmarks in tabs now appends the new tabs rather than overwriting.
    • Location and Search bar size can now be customized with a simple resizer item.
    • Text selection improvements: multiple text selections can be made with Ctrl/Cmd; double-click drag selects in “word-by-word” mode; triple-clicking selects a paragraph.
    • Find toolbar: the Find toolbar now opens with the current selection.
    • Plugin management: users can disable individual plugins in the Add-on Manager.
    • Integration with Windows: Firefox now has improved Windows icons, and uses native user interface widgets in the browser and in web forms.
    • Integration with the Mac: the new Firefox theme makes toolbars, icons, and other user interface elements look like a native OS X application. Firefox also uses OS X widgets and supports Growl for notifications of completed downloads and available updates. A combined back and forward control make it even easier to move between web pages.
    • Integration with Linux: Firefox’s default icons, buttons, and menu styles now use the native GTK theme.

    More Personal

    • Star button: quickly add bookmarks from the location bar with a single click; a second click lets you file and tag them.
    • Tags: associate keywords with your bookmarks to sort them by topic.
    • Location bar & auto-complete: type in all or part of the title, tag or address of a page to see a list of matches from your history and bookmarks; a new display makes it easier to scan through the matching results and find that page you’re looking for. Results are returned according to their frecency (a combination of frequency and recency of visits to that page) ensuring that you’re seeing the most relevant matches. An adaptive learning algorithm further tunes the results to your patterns!
    • Smart Bookmarks Folder: quickly access your recently bookmarked and tagged pages, as well as your more frequently visited pages with the new smart bookmarks folder on your bookmark toolbar.
    • Places Organizer: view, organize and search through all of your bookmarks, tags, and browsing history with multiple views and smart folders to store your frequent searches. Create and restore full backups whenever you want.
    • Web-based protocol handlers: web applications, such as your favorite webmail provider, can now be used instead of desktop applications for handling mailto: links from other sites. Similar support is available for other protocols (Web applications will have to first enable this by registering as handlers with Firefox).
    • Download & Install Add-ons: the Add-ons Manager (Tools > Add-ons) can now be used to download and install a Firefox customization from the thousands of Add-ons available from our community add-ons website. When you first open the Add-ons Manager, a list of recommended Add-ons is shown.
    • Easy to use Download Actions: a new Applications preferences pane provides a better UI for configuring handlers for various file types and protocol schemes.

    Improved Platform for Developers

    • New graphics and font handling: new graphics and text rendering architectures in Gecko 1.9 provides rendering improvements in CSS, SVG as well as improved display of fonts with ligatures and complex scripts.
    • Color management: (set gfx.color_management.enabled on in about:config and restart the browser to enable.) Firefox can now adjust images with embedded color profiles.
    • Offline support: enables web applications to provide offline functionality (website authors must add support for offline browsing to their site for this feature to be available to users).
    • A more complete overview of Firefox 3 for developers is available for website and add-on developers.

    Improved Performance

    • Speed: improvements to our JavaScript engine as well as profile guided optimizations have resulted in continued improvements in performance. Compared to Firefox 2, web applications like Google Mail and Zoho Office run twice as fast in Firefox 3, and the popular SunSpider test from Apple shows improvements over previous releases.
    • Memory usage: Several new technologies work together to reduce the amount of memory used by Firefox 3 over a web browsing session. Memory cycles are broken and collected by an automated cycle collector, a new memory allocator reduces fragmentation, hundreds of leaks have been fixed, and caching strategies have been tuned.
    • Reliability: A user’s bookmarks, history, cookies, and preferences are now stored in a transactionally secure database format which will prevent data loss even if their system crashes.

    Comments

    « Previous entries