skater coder

angela chng – Ruby on Rails / PHP web developer & skater girl in Singapore

  • blogabout stuff
  • aboutthis website
  • contactdrop a message

You're browsing the
Coding Tips archives

September 4, 2010
Posted by roadburn

Testing Spree with cucumber + spork + autotest + pickle + factory girl

Copy this from the spree root folder into your app

1
2
3
spree-0.11.0/features
to 
yourapp/features

Edit features/support/env.rb

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
ENV["RAILS_ENV"] ||= "cucumber"
 
require 'rubygems'
require 'spork'
 
Spork.prefork do
  require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
 
  require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
  require 'cucumber/rails/world'
  require 'cucumber/rails/active_record'
  require 'cucumber/web/tableish'
 
 
  require 'capybara/rails'
  require 'capybara/cucumber'
  require 'capybara/session'
  require 'cucumber/rails/capybara_javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript
  # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
  # order to ease the transition to Capybara we set the default here. If you'd
  # prefer to use XPath just remove this line and adjust any selectors in your
  # steps to use the XPath syntax.
  Capybara.default_selector = :css
 
 
  Dir.glob(SPREE_ROOT + '/db/default/*.{yml,csv,rb}').each do |file|
    Fixtures.create_fixtures(SPREE_ROOT + '/db/default', File.basename(file, '.*'))
  end
  Dir.glob(SPREE_ROOT + '/test/fixtures/*.{yml,csv,rb}').each do |file|
    Fixtures.create_fixtures(SPREE_ROOT + '/test/fixtures', File.basename(file, '.*'))
  end
 
  require 'faker'
  require 'factory_girl'
 
  [ File.join(SPREE_ROOT, 'test', 'factories', '*.rb'),
    File.join(RAILS_ROOT, 'vendor', 'extensions', '*',
      '{test,spec}', 'factories', '*.rb')
  ].each do |path|
    Dir.glob(path).each { |factory| require factory }
  end
 
  require 'factory_girl/step_definitions'
 
  Zone.class_eval do
    def self.global
      find_by_name("GlobalZone") || Factory(:global_zone)
    end
  end
 
  Product.class_eval do
    def taxon=(taxon_name)
      taxonomy = Taxonomy.find_or_create_by_name("Category")
      taxon = Taxon.find_or_create_by_name_and_taxonomy_id(taxon_name, taxonomy)
      self.taxons << taxon
    end
  end
 
  ShippingMethod.create(:name => "UPS Ground", :zone => Zone.global, :calculator => Calculator::FlatRate.new)
 
  coupon = Coupon.create(:code => "SPREE", :description => "$5 off any order", :combine => false, :calculator => Calculator::FlatRate.new)
  coupon.calculator.update_attribute(:preferred_amount, 5)
 
end
 
Spork.each_run do
  # If you set this to false, any error raised from within your app will bubble
  # up to your step definition and out to cucumber unless you catch it somewhere
  # on the way. You can make Rails rescue errors and render error pages on a
  # per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
  #
  # If you set this to true, Rails will rescue all errors and render error
  # pages, more or less in the same way your application would behave in the
  # default production environment. It's not recommended to do this for all
  # of your scenarios, as this makes it hard to discover errors in your application.
  ActionController::Base.allow_rescue = false
 
  # If you set this to true, each scenario will run in a database transaction.
  # You can still turn off transactions on a per-scenario basis, simply tagging
  # a feature or scenario with the @no-txn tag. If you are using Capybara,
  # tagging with @culerity or @javascript will also turn transactions off.
  #
  # If you set this to false, transactions will be off for all scenarios,
  # regardless of whether you use @no-txn or not.
  #
  # Beware that turning transactions off will leave data in your database
  # after each scenario, which can lead to hard-to-debug failures in
  # subsequent scenarios. If you do this, we recommend you create a Before
  # block that will explicitly put your database in a known state.
  Cucumber::Rails::World.use_transactional_fixtures = true
 
  # How to clean your database when transactions are turned off. See
  # http://github.com/bmabey/database_cleaner for more info.
  require 'database_cleaner'
  DatabaseCleaner.strategy = :truncation
end

config/cucumber.yml

1
2
3
4
5
6
7
8
9
<%
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
rerun_opts = rerun.to_s.strip.empty? ? "--format progress features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
std_opts = "#{rerun_opts} --format rerun --out rerun.txt --strict --tags ~@wip"
%>
default: --drb <%= std_opts %>
wip: --drb --tags @wip:3 --wip features
autotest: --drb features --guess --format 'pretty' --color
autotest-all: --drb features --guess --format 'progress' --color

config/environments/cucumber.rb

1
2
ENV['AUTOFEATURE'] = "true"
ENV['RSPEC'] = "true"

config/database.yml

1
2
cucumber:
  <<: *test

Run your tests!

1
2
$ spork cuc
$ autotest

Resources

http://groups.google.com/group/spree-user/browse_thread/thread/81b006af48d3166d

1 Comment

Posted Under Coding Tips Rails

August 31, 2010
Posted by roadburn

Commonly used Rails 2.3 commands

Rails

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
Setup rails app with mysql
$ rails appname -d mysql
 
Start server with debugging enabled
$ script/server --debugger
 
Start server with debugging enabled - specify environment
$ script/server --debugger RAILS_ENV=production
 
Install required gems
$ sudo rake gems:install
 
Run gem server for rdocs
$ gem server
 
View routes 
$ rake routes
 
Update Rails
$ rake rails:update
 
Enter the console with specified environment
$ script/console
$ script/console development
$ script/console test
$ script/console production
 
Clear logfiles
$ rake log:clear

Database

1
2
3
4
5
6
7
8
9
10
11
Create database
$ rake db:create
 
Run database migrations
$ rake db:migrate
 
Drop database
$ rake db:drop
 
Rollback database migration
$ rake db:rollback

Testing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Clone database for testing
$ rake db:test:clone
 
Bootstrap Rspec
$ script/generate rspec
 
Bootstrap Cucumber
$ script/generate cucumber --rspec --capybara --spork
 
Bootstrap Pickle
$ script/generate pickle
 
Generate Rspec model
$ script/generate rspec_model singularmodelname
 
Generate Rspec controller
$ script/generate rspec_controller pluralmodelname
 
Start spork for cucumber
$ spork cuc
 
Run autotest
$ autotest

Gems

1
2
3
4
5
6
7
8
9
10
11
Install gems
$ sudo gem install gemname
 
Uninstall gems
$ sudo gem uninstall gemname
 
Reinstall gems
$ sudo gem pristine --all
 
Remove old gems
$ sudo gem clean

Generators

1
2
Generate migration
$ script/generate migration the_migration_name

Heroku

1
2
Push to Git
$ git push heroku

No Comments

Posted Under Coding Tips Rails


Posted by roadburn

How to upload multiple files on rails (uploadify + paperclip + jquery)

Setting Up

Download Uploadify from
http://www.uploadify.com/

copy the uploadify files into the following directories

1
2
3
4
5
6
7
public/javascripts/uploadify/jquery.uploadify-2.1.0.min.js
public/javascripts/uploadify/uploadify.swf
public/javascripts/uploadify/swfobject.js
 
public/images/cancel.png
 
public/stylesheets/uploadify.css

Create this file
app/middleware/flash_session_cookie_middleware.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'rack/utils' 
class FlashSessionCookieMiddleware 
  def initialize(app, session_key = '_session_id') 
    @app = app 
    @session_key = session_key 
  end 
 
  def call(env) 
    if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/ 
      req = Rack::Request.new(env) 
      env['HTTP_COOKIE'] = "#{@session_key}=#{req.params[@session_key]}".freeze unless req.params[@session_key].nil? 
    end 
    @app.call(env) 
  end 
end

Add this line to
config/initializers/session_store.rb

1
ActionController::Dispatcher.middleware.insert_before(ActionController::Base.session_store, FlashSessionCookieMiddleware, ActionController::Base.session_options[:key])

Make sure your environment.rb file has this

config/environment.rb

1
2
3
4
5
6
7
8
9
Rails::Initializer.run do |config|
 
  config.gem 'mime-types', :lib => 'mime/types'
  config.gem 'paperclip' 
 
  %w(middleware).each do |dir| 
    config.load_paths << "#{RAILS_ROOT}/app/#{dir}" 
  end
end

Models

Let’s assume you want to create a photo album with many photos.

Create your photo model with the following:

db/migrate/create_photos.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CreatePhotos < ActiveRecord::Migration
  def self.up
    create_table :photos do |t|
      t.integer :attachable_id
      t.string :description  
      t.string :data_file_name  
      t.string :data_content_type  
      t.integer :data_file_size  
      t.datetime :data_updated_at
      t.string :parent  
    end
  end
 
  def self.down
    drop_table :images
  end
end

In your album model:

app/model/album.rb

1
has_many :photos, :dependent => :destroy, :foreign_key => :attachable_id

In your photo model:
app/model/photo.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
belongs_to :album, :foreign_key => :attachable_id
 
has_attached_file :data, 
      :url => "/assets/images/:id/:style/:basename.:extension",
      :path => ":rails_root/public/assets/images/:id/:style/:basename.:extension",
      :styles => { 
      :large => "800x800>", 
      :medium => "300x300>", 
      :thumb => "100x100#"}
 
validates_attachment_presence :data
validates_attachment_size :data, :less_than => 2.megabytes  
validates_attachment_content_type :data, :content_type => ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']

Controllers

app/controllers/photos_controller.rb

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
class PhotosController < ApplicationController 
  def create
 
    newparams = coerce(params) 
    @photo = Photo.new(newparams[:upload]) 
 
    // so this photo can belong to other models other than album
    @parent = @photo.parent.constantize.find(@photo.attachable_id)
 
    if @photo.save
      flash[:notice] = "Successfully uploaded photo."
      respond_to do |format| 
        format.html {redirect_to @parent} 
        format.json  { render :json => { :result => 'success', :upload => photo_path(@photo) } } 
      end 
    else
      flash[:notice] = "Only gif, jpg or png files allowed"
      respond_to do |format| 
        format.html {redirect_to @parent} 
        format.json  { render :json => { :result => 'failed'} } 
      end
    end
 
  end
 
  def show
    @photo = Photo.find(params[:id])    
  end
 
  def coerce(params) 
    if params[:upload].nil? 
      h = Hash.new 
      h[:upload] = Hash.new 
      h[:upload][:attachable_id] = params[:attachable_id] 
      h[:upload][:parent] = params[:parent] 
      h[:upload][:data] = params[:Filedata] 
      h[:upload][:data].content_type =  MIME::Types.type_for(h[:upload][:data].original_filename).to_s 
      h 
    else 
      params 
    end 
  end
end

Views

app/views/albums/show.html.erb

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
<%= stylesheet_link_tag "uploadify"  %>
<%= javascript_include_tag "uploadify/swfobject", "uploadify/jquery.uploadify.v2.1.0.min.js" %>
 
<%- session_key_name = ActionController::Base.session_options[:key] -%>
 
<script type="text/javascript" charset="utf-8"> 
jQuery.noConflict();
 
jQuery().ready(function() { 
   jQuery('#photo_upload').click(function(event){ 
      event.preventDefault(); 
   }); 
 
  jQuery('#photo_upload').uploadify({ 
 
    'uploader'    : '/javascripts/uploadify/uploadify.swf', 
    'script'      : '/cms/photos', 
    'multi'       : true, 
    'cancelImg' : '/photos/cancel.png',
 
    onComplete : function(event, queueID, fileObj, response, data) { 
	var dat = eval('(' + response + ')'); 
	if (dat.result=='success'){
 	  jQuery.getScript(dat.upload);
        }else{
	  alert("Only .jpg, .gif, .png files under 2MB allowed. ")
	}
    }, 
 
    'scriptData' : { 'format' : 'json', 
      '<%= session_key_name %>' : encodeURIComponent('<%= u cookies[session_key_name] %>'), 
      'authenticity_token' : encodeURIComponent('<%= u form_authenticity_token if protect_against_forgery? %>'), 
      'attachable_id' 	: '<%= @album.id %>',
      'parent' 	: 'Album'} 
    }); 
    jQuery('#photo_submit').click(function(event){ 
      event.preventDefault(); 
      jQuery('#photo_upload').uploadifyUpload(); 
    }); 
  }); 
</script>
 
<% form_for Image.new(:attachable_id => @deal.id), :html => { :multipart => true } do |f| %>
	<div class="image-uploader">
		<%= f.file_field :data, :id => 'image_upload'  %>
		<%= f.submit "Upload Images", :id => 'image_submit'%>
	</div>
<% end %>

Resources

Many thanks to the following articles that helped me figure out how to get this working
Please follow the links for more detailed explanations

http://fencore.posterous.com/uploadify-with-paperclip-on-rails-tutorial
http://timmyc.posterous.com/uploadify-on-rails-with-paperclip
http://www.practicalecommerce.com/blogs/post/432-Multiple-Attachments-in-Rails
http://www.utoronto.ca/web/htmldocs/book/book-3ed/appb/mimetype.html
http://en.wikipedia.org/wiki/Internet_media_type

2 Comments

Posted Under Coding Tips Rails

March 25, 2009
Posted by roadburn

MySQL – Select rows from Table A that do not exist in Table B

Here’s a useful MySQL code snippet:

Select rows from table A that do not exist in table B

1
SELECT FROM A WHERE id NOT IN (SELECT id FROM B)

No Comments

Posted Under Coding Tips

February 25, 2009
Posted by roadburn

How to: Install php zip on mac osx leopard

Need to install PHP zip on your mac?

It’s easy :)

1
$sudo pecl install zip

No Comments

Posted Under Coding Tips

January 31, 2009
Posted by roadburn

Set MySQL default charset to UTF8

In the /etc/my.cnf file add

1
2
3
4
5
6
7
8
9
10
[mysqld]
#
# * Basic Settings
#
 
# utf8
init-connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_general_ci
default-collation=utf8_general_ci

No Comments

Posted Under Coding Tips

July 23, 2008
Posted by roadburn

Install webmin on ubuntu

http://onlyubuntu.blogspot.com/2007/05/how-to-install-webmin-in-ubuntu.html

wget http://prdownloads.sourceforge.net/webadmin/webmin_1.340_all.deb

sudo dpkg -i webmin_1.340_all.deb

If libraries are missing..

sudo apt- get install -f

No Comments

Posted Under Coding Tips

  • CATEGORIES
    • Coding Tips
    • ExtJS 4
    • Food
    • Portfolio
    • Rails
    • Sharepoint
    • Ubuntu
    • Wordpress

  • TAGS
    activities AD ADAM ajax architecture authentication bluehost books custom application custom form date design disk partition ECTS event id eventid moss forum guid hotfix iis imap keberos list id lists masterpage moss mysite profiles Rails rails 2.0 reporting services ruby Sharepoint sharepoint 2007 site templates site usage sql server 2005 time updates vhd virtual pc visual studio webparts workflow wss

Subscribe via RSS