You can get mongomapper, will paginate and draper to work together like the demos on (https://github.com/mislav/will_paginate) if you access the models in the controller like below
@models = ModelDecorator.
decorate(Model.paginate(:page => params[:page]))
One plus one equals zero
An insight into the mind of tekkies: techie, techy [ˈtɛkɪ] Informal n pl techies a person(s) who is skilled in the use of technological devices, such as computers adj of, relating to, or skilled in the use of technological devices, such as computers
Tuesday, 15 November 2011
Friday, 14 October 2011
Continuous Integration - Headless JS on CentOS
This was a bit of a pain to get working so I thought I would layout the steps to get Continuous Integration (CI) working on CentOS 5.5 with cruise control, rspec and cucumber when you have javascript scenarios you want to run without a real browser.
Before Cruise Control is set up:
1) Clone the latest version of CC from: http://cruisecontrolrb.thoughtworks.com/documentation to your server. (read the guide, update your database.yml etc...)
2) CC can run standalone so start the server. and add your project(s)
3) If you have apache running you will have to set up a virtual host and set it to run as a proxy to the CI e.g. my configuration is:
ServerAdmin EMAIL_ADDRESS
ServerName DOMAIN_NAME
ErrorLog PATH_TO_ERROR_LOG
CustomLog PATH_TO_CUSTOM_LOG
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]
Thanks TomJ.
4) vim lib/tasks/custom_cc.rake
desc 'Custom curise task for RSpec'
task :cruise do
ENV['RAILS_ENV'] = 'test'
if File.exists?(Dir.pwd + "/config/database.yml")
if Dir[Dir.pwd + "/db/migrate/*.rb"].empty?
raise "No migration scripts found in db/migrate/ but database.yml exists, " +
"CruiseControl won't be able to build the latest test database. Build aborted."
end
# perform standard Rails database cleanup/preparation tasks if they are defined in project
# this is necessary because there is no up-to-date development database on a continuous integration box
if Rake.application.lookup('db:test:purge')
CruiseControl::invoke_rake_task 'db:test:purge'
end
if Rake.application.lookup('db:migrate')
CruiseControl::reconnect
CruiseControl::invoke_rake_task 'db:migrate'
end
end
CruiseControl::invoke_rake_task 'spec'
CruiseControl::invoke_rake_task 'cucumber:ok'
end
After Cruise Control is set up
If all is going well then you should be able to start the builder for that project and it should be running the rspec and cucumber tests suite. Now you hit the requirement of writing the scenarios that require javascript and these are currently failing (not unexpected since we don't have a X11 system or browser installed). There are a couple of ways to get these tests running the method I chose was:
1. Add capybara-webkit and headless to the Gemfile:
group :test, :cucumber do
....
gem 'headless'
gem 'capybara-webkit'
....
end
2. Update the features/support/env.rb. Require headless and start it. Also set the capybara js driver to webkit.
require 'cucumber/rails'
require 'headless'
headless = Headless.new
headless.start
Capybara.javascript_driver = :webkit
Capybara.default_selector = :css
Capybara.server_boot_timeout = 50
ActionController::Base.allow_rescue = false
begin
DatabaseCleaner.strategy = :transaction
rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end
3. Now on the CI server we need to install some packages for the capybara-webkit gem (I hope you have permission)
sudo yum install -y Xvfb
sudo yum install -y qt4 qt4-devel
4. Almost there. Start the screen or capybara will give you an error like "webkit_server: cannot connect to X server"
Xvfb :1 -screen 0 1024x768x16 -nolisten inet6 &
It should now be running in the background, you can check ps or jobs
5. Kill the builder and reboot the CI app and then push the earlier changes. When you start the builder again all the tests should now run and if you're lucky they may even pass.
Before Cruise Control is set up:
1) Clone the latest version of CC from: http://cruisecontrolrb.thoughtworks.com/documentation to your server. (read the guide, update your database.yml etc...)
2) CC can run standalone so start the server. and add your project(s)
3) If you have apache running you will have to set up a virtual host and set it to run as a proxy to the CI e.g. my configuration is:
ServerAdmin EMAIL_ADDRESS
ServerName DOMAIN_NAME
ErrorLog PATH_TO_ERROR_LOG
CustomLog PATH_TO_CUSTOM_LOG
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]
Thanks TomJ.
4) vim lib/tasks/custom_cc.rake
desc 'Custom curise task for RSpec'
task :cruise do
ENV['RAILS_ENV'] = 'test'
if File.exists?(Dir.pwd + "/config/database.yml")
if Dir[Dir.pwd + "/db/migrate/*.rb"].empty?
raise "No migration scripts found in db/migrate/ but database.yml exists, " +
"CruiseControl won't be able to build the latest test database. Build aborted."
end
# perform standard Rails database cleanup/preparation tasks if they are defined in project
# this is necessary because there is no up-to-date development database on a continuous integration box
if Rake.application.lookup('db:test:purge')
CruiseControl::invoke_rake_task 'db:test:purge'
end
if Rake.application.lookup('db:migrate')
CruiseControl::reconnect
CruiseControl::invoke_rake_task 'db:migrate'
end
end
CruiseControl::invoke_rake_task 'spec'
CruiseControl::invoke_rake_task 'cucumber:ok'
end
After Cruise Control is set up
If all is going well then you should be able to start the builder for that project and it should be running the rspec and cucumber tests suite. Now you hit the requirement of writing the scenarios that require javascript and these are currently failing (not unexpected since we don't have a X11 system or browser installed). There are a couple of ways to get these tests running the method I chose was:
1. Add capybara-webkit and headless to the Gemfile:
group :test, :cucumber do
....
gem 'headless'
gem 'capybara-webkit'
....
end
2. Update the features/support/env.rb. Require headless and start it. Also set the capybara js driver to webkit.
require 'cucumber/rails'
require 'headless'
headless = Headless.new
headless.start
Capybara.javascript_driver = :webkit
Capybara.default_selector = :css
Capybara.server_boot_timeout = 50
ActionController::Base.allow_rescue = false
begin
DatabaseCleaner.strategy = :transaction
rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end
3. Now on the CI server we need to install some packages for the capybara-webkit gem (I hope you have permission)
sudo yum install -y Xvfb
sudo yum install -y qt4 qt4-devel
4. Almost there. Start the screen or capybara will give you an error like "webkit_server: cannot connect to X server"
Xvfb :1 -screen 0 1024x768x16 -nolisten inet6 &
It should now be running in the background, you can check ps or jobs
5. Kill the builder and reboot the CI app and then push the earlier changes. When you start the builder again all the tests should now run and if you're lucky they may even pass.
Tuesday, 16 August 2011
Passenger with multiple ruby versions
Hey guys, been investigating a little, and I think this article is a summary of why its a problem http://robaldred.co.uk/2011/06/running-passenger-with-multiple-different-ruby-versions-apache-nginx-rvm/.
Passenger does not support this yet. So unfortunately we will have to wait for a future passenger until we start using rvm in prod and hopefully until then we will only need REE and wont need things like better unicode support ☃ Anyway I have been playing around with the set up of rvm, rails, nginx and passenger and have it working nicely locally.
On a mac we can start services at boot by creating a plist file. Here is my /System/Library/LaunchDaemons/nginx.plist
We can set default rvm with rvm ree --default
and use --passenger flag
rvm use ree
gem install passenger
passenger-install-nginx-module
here is the config with ree and rvm.
This just says use the passenger installed with my ree ruby (as the memory benefits go hand in hand)
There was a little trouble with dependencies and gpg so may revisit this later.
Here is some information on Apache Nginx showdown: http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/.
Maybe we load balance an nginx for slow clients in the future? Will investigate more
Passenger does not support this yet. So unfortunately we will have to wait for a future passenger until we start using rvm in prod and hopefully until then we will only need REE and wont need things like better unicode support ☃ Anyway I have been playing around with the set up of rvm, rails, nginx and passenger and have it working nicely locally.
On a mac we can start services at boot by creating a plist file. Here is my /System/Library/LaunchDaemons/nginx.plist
<?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>Label</key>
<string>nginx</string>
<key>Program</key>
<string>/opt/nginx/sbin/nginx</string>
<key>KeepAlive</key>
<true/>
<key>StandardErrorPath</key>
<string>/opt/nginx/logs/error.log</string>
<key>LaunchOnlyOnce</key>
<true/>
</dict>
</plist>
sudo launchctl load -w /System/Library/LaunchDaemons/nginx.plist
and unload respectively. I may create an alias for this.
We can set default rvm with rvm ree --default
and use --passenger flag
rvm use ree
gem install passenger
passenger-install-nginx-module
here is the config with ree and rvm.
/opt/nginx/conf/nginx.conf
passenger_root /Users/crawford/.rvm/gems/ree-1.8.7-2011.03/gems/passenger-3.0.7;
passenger_ruby /Users/crawford/.rvm/wrappers/ree-1.8.7-2011.03/ruby;
This just says use the passenger installed with my ree ruby (as the memory benefits go hand in hand)
There was a little trouble with dependencies and gpg so may revisit this later.
Here is some information on Apache Nginx showdown: http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/.
Maybe we load balance an nginx for slow clients in the future? Will investigate more
Thursday, 23 June 2011
Setting Up SSL For Your Local Development Environment
The web server Mongrel does not support SSL on its own, in Production we would use something like Apache, Passenger and a Mongrel Cluster. Apache would deal with the SSL and then pass on a header to each Mongrel server, this allows for many benefits, including performance. However this is not really a lightweight enough for agile development. Instead we can use an Apache server as a proxy server to deal with SSL and to pass on the correct header for Mongrel to understand. Once we have configured our proxy server it sits in front and just passes on all requests, the server can start on a local machines system at bootup and should not need to be restarted, so essentially it is invisible to the developer.
We can still continue to use our Mongrel server by itself with no additional configuration, but we can now configure any API URL calls to the new proxy, normal testing can continue with just the normal Mongrel server for our application.
Creating a Self Signed Certificate
The easiest way to create our certificate and key files is with the following command:
make sure to add the servername '''localhost''' when it asks for your name (e.g. YOURNAME)
These files can be kept anywhere, for example I keep mine in
Setting up Apache and Creating our Proxy Virtual Host
First we must make sure Apache2 is installed run the command:
First lets enable all the modules we will need by running the following commands:
Now we must update the proxy module to allow proxy requests from localhost by changing the following lines in /etc/apache2/mods-enabled/proxy.conf
Next we can add a file with the following virtual host in it to /etc/apache2/sites-available
We should disable the default site using:
and enable the new one using:
We can run the following commands to start and stop the Apache server
/etc/init.d/apache2 start
/etc/init.d/apache2 stop
/etc/init.d/apache2 restart
We should be able to view the error logs at:
Pointing the Application to a local URL
If we want an application, such as the whitelabel application to make secure HTTPS API calls to our main platform locally then we can now configure the API URL as follows:
We can still continue to use our Mongrel server by itself with no additional configuration, but we can now configure any API URL calls to the new proxy, normal testing can continue with just the normal Mongrel server for our application.
Creating a Self Signed Certificate
The easiest way to create our certificate and key files is with the following command:
openssl req -new -x509 -nodes -out server.crt -keyout server.key
make sure to add the servername '''localhost''' when it asks for your name (e.g. YOURNAME)
These files can be kept anywhere, for example I keep mine in
/home//SSL/
Setting up Apache and Creating our Proxy Virtual Host
First we must make sure Apache2 is installed run the command:
sudo apt-get install Apache2
First lets enable all the modules we will need by running the following commands:
sudo a2enmod proxy
sudo a2enmod headers
sudo a2enmod ssl
Now we must update the proxy module to allow proxy requests from localhost by changing the following lines in /etc/apache2/mods-enabled/proxy.conf
<proxy>
AddDefaultCharset off
Order deny,allow
Allow from localhost
</proxy>
Next we can add a file with the following virtual host in it to /etc/apache2/sites-available
<ifmodule c="">
SSLCertificateFile <path to="" certificate="">/server.crt
SSLCertificateKeyFile <path to="" key="">/server.key
SSLSessionCache none
<virtualhost 443="">
SSLEngine on
SSLProxyEngine on
# This is required to set the header for Mongrel to treat it as the correct request
RequestHeader set X_FORWARDED_PROTO 'https'
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPreserveHost on
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</virtualhost>
</path></path></ifmodule>
We should disable the default site using:
sudo a2dissite default
and enable the new one using:
sudo a2ensite sitename
We can run the following commands to start and stop the Apache server
/etc/init.d/apache2 start
/etc/init.d/apache2 stop
/etc/init.d/apache2 restart
We should be able to view the error logs at:
/var/log/apache2/
Pointing the Application to a local URL
If we want an application, such as the whitelabel application to make secure HTTPS API calls to our main platform locally then we can now configure the API URL as follows:
API_URL = https://localhost:443
Wednesday, 15 June 2011
Android, Fedora Core 15
FC15 comes installed with Eclipse Helios. When following the google guide for installing the ADT plugin you might see errors like
missing "org.eclipse.wst.sse.core 0.0.0"
This is because the guide is based on Galileo so to get around this make sure you add http://download.eclipse.org/releases/helios to the add new software section of Eclipse. Now when you try to install the plugin any prerequisites will also be installed.
Next step download the android SDK and update the path in the Eclipse properties. Once you have an AVD set up you should then be able to run your app.
missing "org.eclipse.wst.sse.core 0.0.0"
This is because the guide is based on Galileo so to get around this make sure you add http://download.eclipse.org/releases/helios to the add new software section of Eclipse. Now when you try to install the plugin any prerequisites will also be installed.
Next step download the android SDK and update the path in the Eclipse properties. Once you have an AVD set up you should then be able to run your app.
Saturday, 28 May 2011
Fedora Core 15 - Dell Studio 15 - Broadcom Wireless internet
Massive problems getting my wireless working on the latest and greatest Fedora Core 15! I was upgrading from FC13 and the previous broadcom-wl drivers were not supported on the new kernel. Here is how I fixed it.
Check that your card is supported
lspci -nn
04:00.0 Network controller [0280]: Broadcom Corporation BCM4313 802.11b/g LP-PHY [14e4:4727] (rev 01)
Download the hybrid driver source http://www.broadcom.com/support/802.11/linux_sta.php
Follow the readme steps to disable any existing configuration
Untar and try to make (this will probably fail do you to an error with the source with the c compiler. To resolve find line 485 and replace
init_MUTEX(&wl->sem);
with
sema_init(&wl->sem, 1);
FYI - I read that on another blog but lost the link.
run make again and this time you should be able to compile. Then make install. You should now be able to get the wireless to work
modprobe lib80211 (required for security)
modprode wl.ko or insmod wl.ko
You should be able to run iwlist scanning etc... to connect now.
To automate the wireless to boot on load I added the commands above to /etc/rc.local
Reboot and you should be good to go.
Check that your card is supported
lspci -nn
04:00.0 Network controller [0280]: Broadcom Corporation BCM4313 802.11b/g LP-PHY [14e4:4727] (rev 01)
Download the hybrid driver source http://www.broadcom.com/support/802.11/linux_sta.php
Follow the readme steps to disable any existing configuration
Untar and try to make (this will probably fail do you to an error with the source with the c compiler. To resolve find line 485 and replace
init_MUTEX(&wl->sem);
with
sema_init(&wl->sem, 1);
FYI - I read that on another blog but lost the link.
run make again and this time you should be able to compile. Then make install. You should now be able to get the wireless to work
modprobe lib80211 (required for security)
modprode wl.ko or insmod wl.ko
You should be able to run iwlist scanning etc... to connect now.
To automate the wireless to boot on load I added the commands above to /etc/rc.local
Reboot and you should be good to go.
Thursday, 19 May 2011
Using virtual attributes in ruby model.to_xml
If you have virtual attributes that you want to include in your to_xml call then you can override the to_xml on the model and pass the virtual attributes as methods. For example
115true
115trueAn Example from another model
class ModelName < ActiveRecord::Base
has_one :model_name_2
# real attributes a, b
attr_accessor :c, :d
delegate e, :to => :model_name_2
end
Now an instance (mn) of type ModelName calling to_xml will output
mn.to_xml
Now to override the to_xml to include attributes c, d and e.
class ModelName < ActiveRecord::Base
has_one :model_name_2
class ModelName < ActiveRecord::Base
has_one :model_name_2
# real attributes a, b
attr_accessor :c, :d
delegate e, :to => :model_name_2
def to_xml
super(:methods => [:c, :d, e])
end
end
Now when to_xml is called on the model c, d and e will also be included.
mn.to_xml
more to_xml goodness at http://apidock.com/rails/ActiveRecord/Serialization/to_xml
Subscribe to:
Posts (Atom)