Posts Tagged ‘Ruby on Rails’
When you’re debugging/analyzing MySQL queries in the Rails console, it helps to turn on ActiveRecord logging:
#Enable ActiveRecord logging def loud_logger(enable = true) logger = (enable == true ? Logger.new(STDOUT) : nil) ActiveRecord::Base.logger = logger ActiveRecord::Base.clear_active_connections! end
Assuming you want to make sure that no two models have the same COMBINATION of values for a and b:
so having two models with:
a = 1, b = 2
a = 1, b = 3
would not be a conflict.
If that’s the case then the standard validation
class Widget < ActiveRecord::Base
validates_uniqueness_of :a, :b
end
wouldn’t work since it tries to prevent saving two models with the same value of a, OR with the same value of b.
And even if that’s not what you’re trying to do, and you’re ok with the example being a conflict, validates_uniqueness_of doesn’t guarantee uniqueness if two users try to save conflicting records simultaneously. The validation works by first trying to find a record with the value, and if it doesn’t find it inserting the ‘new’ record, and this can fail due to a concurrency hole.
To fill this hole requires leaning on the database server, and the way to do that in SQL is by having a unique index on the table which covers the column or columns you want to be unique. This assume you are using a database which supports it, e.g. MySql.
To create an index you can create a migration which includes a statement like
add_index :widgets, [:a, :b], :unique => true)
Assuming that the table name for the model is ‘widgets’
Now if you do this, you also need to be aware that if you try to save a record with a uniqueness conflict the save will raise an ActiveRecord::StatementInvalid exception, which you’ll need to rescue and do something like telling the user of the conflict so that he can rectify it.
>> ActiveRecord::Base.connection.instance_variable_set :@logger, Logger.new(STDOUT)
I use the Rails console mainly to poke around in my database. Unfortunately the display of the records returned leaves a lot to be desired. Hirb solves this problem perfectly! Here are the quick steps you need to get the basic functionaliy:
- Install the gem: sudo gem install cldwalker-hirb –source http://gems.github.com
- Start the console: ruby script/console
- Require Hirb: require ‘hirb’
- Enable it: Hirb.enable
- Try it: x = Model.find(:all)
I was using the Rails helper observe_field to monitor a text entry form on my web app. I couldn’t figure out why the relevant method was not being called until I realized that it was happening every time there was a single quote in the text entry. The solution is simple. Use the escape_javascript function as shown below:
[ruby]
<%= observe_field :guess,
:frequency => 0.5,
:update => 'ajaxWrapper',
:url => {:action => 'feedback',
nly_path => false},
:with => "'correct=#{escape_javascript(@text)}&guess='+encodeURIComponent(value)" %>
[/ruby]
I highly recommend Bort when you’re starting a new Ruby on Rails project. Assuming you’re using MySQL, the following steps are all that are necessary to get started:
- Download and unzip Bort into project folder
- Edit the database.yml and the settings.yml files
- Create the database: mysqladmin -u <username> -p create <db_name_development>
- If you’re using Dreamhost: add ‘host: mysql.<dbhostname>.com’ to your database.yml file (in the production environment)
- rake db:migrate
The following gems and plugins are the most popular as of Nov 12th, 2008:
- Javascript Framework: jQuery (56%), Prototype (43%)
- Skeleton: Bort
- Mocking: Mocha
- Exception Notification: Hoptoad
- Full text search: Thinking Sphinx
- Uploading: Paperclip
- User authentication: Restful_authentication (keep an eye on Authlogic)
- HTML/XML Parsing: Hpricot
- View Templates: Haml
NewRelic has a good article on the state of the Rails stack.
- Upgrade to latest version of RubyGems (’sudo gem update –system’)
- Add GitHub repository (‘gem sources -a http://gems.github.com’)
- Upgrade to latest version of Ziya (’sudo gem install derailed-ziya’)
- Install Ziya in project directory (‘Ziyafy –charts’ in project home, note the double dash)
- Add ziya.rb to config/initializers directory
- Copy your themes into ../public/themes/
Some other thoughts: If you’re frustrated by the almost non-existent documentation and the fact that the gem is in constant flux, don’t despair. The best way to understand how to customize your graph is to look through the example themes (for some reason they didn’t install with my gem but I downloaded them from GitHub).
Note: You can not instantiate the Ziya object in the controller corresponding to the chart’s view. It needs to be in a separate controller. Otherwise, an XML file (instead of a chart) will be returned when that controller is invoked.
Also, the reference material at XML/SWF charts is very useful and Ziya seems to adhere quite closely to the naming conventions.
I also found that I needed user-defined functions fairly quickly to customize axes etc.
Here is an example of how to use Ziya to create a scatter chart:
== Chart Controller ==
01: def load_ef
02: # Create graph data object
03: chart_data = Array.new04: # Pull portfolios out of database
05: @query = sessions[:period].to_i06: @portfolios = Portfolio.find(:all, :conditions => ["period = ?", @query])
07: # Strip out risk and return
08: @portfolios.each { |x|
09: chart_data << x.std_dev
10: chart_data << x.port_ret
11: }12: title = “User-entered portfolios”
13: chart = Ziya::Charts::Scatter.new(‘LICENSE-KEY’)
14: chart.add( :axis_category_text, %w[x y]*(chart_data.length/2) )
15: chart.add( :series, title, chart_data )16: chart.add( :theme , “assetcorrelation” )
17: respond_to do |fmt|
18: fmt.xml { render : xml => chart.to_xml }
19: end
20: end== View ==
1: <div>
2: <%= ziya_chart load_ef_url, :size => “1200×800″ – %>
3: </div>== Routes.rb ==
1: map.load_ef ‘/chart/load_ef’, :controller => ‘chart’, :action => ‘load_ef’
As far as I understand, Rails will first look for a method in your controller that matches the view, then, once it starts rendering the view, it hits the callback (line 2 in the view snippet above) and at that point calls the method in the chart_controller to render the chart data, using the routing information in Routes.rb.
Note that in this case, I am pulling the data for the chart out of my database.
Keeping Ruby on Rails up to date:
Rails > 2.1 now with gem dependencies and here
ruby -v — check which version of ruby you have installed
rails -v — check which version of rails you have installed
gem list — check versions of all installed gems
sudo gem update — bulk update of all installed gems (some say this is a bad idea)
sudo gem update –system (updates rubygems, note use of double dash)
sudo gem uninstall <gem_name> — uninstall a specific gem
sudo gem install <gem_name> — install a specific gem
sudo gem cleanup — remove old versions of gems
sudo gem install -v=2.0.2 rails — install a specific version of Rails (to stay in synch with Dreamhost)
Rmagick
Installing Rmagick
sudo apt-get updatesudo apt-get install imagemagick- Then, install the imagemagick9 dev library:
sudo apt-get install libmagick9-dev - Last, install the RMagick gem:
sudo gem install rmagick
Rails Migrations
Use rake db:schema:load if having trouble with Rails migrations and you have a working schema.
Use rake db:migrate VERSION=3 to roll back to version 3
Use rake db:migrate:reset — drop db, recreate it, and then run all migrations
rake db:rollback — go back one migration
rake db:migrate:redo — undo last migration and then redo it
rake db:sessions:clear — purge sessions from database
MySQL
To create a new MySQL DB on Dreamhost it is best to use the Dreamhost panel.
To create a database locally: mysqladmin -u root -p create <dbname>_development
mysql -u yourdblogin -p -hyourdbdomain.yourdomain.com yourdb
To load a table into a database:
mysql -u [username] -p[password] -hmysql.[domainname].com [database_name] < iso_country_list.sql
drop table sessions; — delete the sessions table
show tables; — show all tables for database
describe sessions; — show the sessions table
check table sessions; — check the sessions table for corruption and/or nonexistence
Gem Sources
Make sure to add GitHub: gem sources -a http://gems.github.com
If you’re getting this error:
Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)
When you try to execute a migration, it might be worth trying:
rake db:migrate RAILS_ENV=production
I’m sure this could be solved in a configuration file – database.yml (?) – but that worked for me.
Also, on Dreamhost, make sure to add the following line
‘host: mysql.<dbhostname>.com’ to your database.yml file (under the production environment)
