SlideShare una empresa de Scribd logo
1 de 168
Descargar para leer sin conexión
Your own gem                   (little)




building an online business with Ruby

    Lindsay Holmwood <lindsay@holmwood.id.au>
(.com)
business

development

 operations
have an idea
check that it’s profitable
apples           oranges




are both fruit
web store       book shop




are both businesses
financials
are important.
do them!
(conservative estimates are best)
check your tech
time is an expense
halve your deliverables
then halve them again
1-2 core features
write ideas down
development
Merb     (merbivore.com)




development
Merb     (merbivore.com)




DataMapper           (datamapper.org)




development
Merb       (merbivore.com)




DataMapper             (datamapper.org)




MooTools         (mootools.net)




development
development
bootstrap
$ sudo gem install merb-core merb-more




bootstrap
$ sudo gem install merb-core merb-more

$ sudo gem install dm-core dm-more do_sqlite3




bootstrap
$ sudo gem install merb-core merb-more

$ sudo gem install dm-core dm-more do_sqlite3

$ merb-gen app schoonerwatch.com




bootstrap
$ sudo gem install merb-core merb-more

$ sudo gem install dm-core dm-more do_sqlite3

$ merb-gen app schoonerwatch.com

$ cd schoonerwatch.com




bootstrap
$ sudo gem install merb-core merb-more

$ sudo gem install dm-core dm-more do_sqlite3

$ merb-gen app schoonerwatch.com

$ cd schoonerwatch.com

$ bzr init ; bzr add

$ bzr commit -m quot;initial commitquot;




bootstrap
$ sudo gem install merb-core merb-more

$ sudo gem install dm-core dm-more do_sqlite3

$ merb-gen app schoonerwatch.com

$ cd schoonerwatch.com

$ bzr init ; bzr add

$ bzr commit -m quot;initial commitquot;




                       s/bzr/git/g
bootstrap
merb-gen
$ merb &




merb-gen
$ merb &

$ merb-gen resource pub




merb-gen
$ merb &

$ merb-gen resource pub

$ bzr commit -m quot;added merb-gen'd pub resourcequot;




merb-gen
$ merb &

$ merb-gen resource pub

$ bzr commit -m quot;added merb-gen'd pub resourcequot;

$ vim spec/spec.opts spec/spec_helper.rb




merb-gen
--colour
--format
profile




spec/spec.opts
...

Spec::Runner.configure do |config|
  config.include(Merb::Test::ViewHelper)
  config.include(Merb::Test::RouteHelper)
  config.include(Merb::Test::ControllerHelper)
end

DataMapper.auto_migrate!




spec/spec_helper.rb
run specs
$ rake spec:request




run specs
$ rake spec:request

.**......

Pending:
resource(:pubs) GET contains a list of pubs (TODO)
  Called from ./spec/requests/pubs_spec.rb:21
resource(:pubs) GET has a list of pubs (TODO)
  Called from ./spec/requests/pubs_spec.rb:33

Finished in 0.322787 seconds

9 examples, 0 failures, 2 pending



run specs
request specs
$ vim spec/requests/pubs_spec.rb




request specs
$ vim spec/requests/pubs_spec.rb

...

it quot;contains a sorted list of pubsquot; do
  @response.should have_xpath(quot;//h3[contains(.,'Cheapest')]quot;)
  @response.should have_xpath(quot;//h3[contains(.,'Nearest')]quot;)
end




request specs
run specs
$ rake spec:request




 run specs
$ rake spec:request

Pending:
resource(:pubs) GET has a list of pubs (TODO)
  Called from ./spec/requests/pubs_spec.rb:33

1)
'resource(:pubs) GET contains a sorted list of pubs' FAILED
expected following text to match xpath //h3[contains(.,'Cheapest')]’
./spec/requests/pubs_spec.rb:21:

Finished in 0.411139 seconds

9 examples, 1 failure, 1 pending




  run specs
haml
$ vim config/dependencies.rb




haml
$ vim config/dependencies.rb

...

dependency quot;merb-hamlquot;, merb_gems_version




haml
$ vim config/dependencies.rb

...

dependency quot;merb-hamlquot;, merb_gems_version


$ vim config/init.rb




haml
$ vim config/dependencies.rb

...

dependency quot;merb-hamlquot;, merb_gems_version


$ vim config/init.rb

...

use_template_engine :haml




haml
hamlise view
$ bzr mv app/views/pubs/index.html.erb 
         app/views/pubs/index.html.haml




hamlise view
$ bzr mv app/views/pubs/index.html.erb 
         app/views/pubs/index.html.haml

$ vim app/views/pubs/index.html.haml




hamlise view
$ bzr mv app/views/pubs/index.html.erb 
         app/views/pubs/index.html.haml

$ vim app/views/pubs/index.html.haml
%h3 Nearest
%h3 Cheapest




hamlise view
$ bzr mv app/views/pubs/index.html.erb 
         app/views/pubs/index.html.haml

$ vim app/views/pubs/index.html.haml
%h3 Nearest
%h3 Cheapest

$ rake spec:request

Pending:
resource(:pubs) GET has a list of pubs (TODO)
  Called from ./spec/requests/pubs_spec.rb:33

Finished in 0.389194 seconds

9 examples, 0 failures, 1 pending



hamlise view        tests pass!
model specs
$ vim spec/models/pubs_spec.rb




model specs
$ vim spec/models/pubs_spec.rb

1.




model specs
$ vim spec/models/pubs_spec.rb

1.   it quot;should have name, address, pricequot; do
       @pubs.each do |pub|
         pub.name.should_not be_nil
         pub.address.should_not be_nil
         pub.price.should_not be_nil
       end
     end




model specs
$ vim spec/models/pubs_spec.rb

2.   it quot;should handle different url formatsquot; do
       @pubs.each do |pub|
         pub.url = 'mygreatpub.com.au'
         pub.save.should be_true
         pub.url = 'http://mygreatpub.com.au/'
         pub.save.should be_true
       end
     end




model specs
$ vim spec/models/pubs_spec.rb

3.   it quot;should consistently format + store urlsquot; do
       @pubs.each do |pub|
         adjective = %w[great swanky awesome stylish][rand(4)]
         pub.url = quot;#{adjective}pub.com.auquot;
         pub.save.should be_true
         pub.url.should =~ /^http://.+/$/
       end
     end




model specs
model specs
$ vim spec/models/pubs_spec.rb

before(:each) do
  @pubs = 10.of { Pub.generate }
end




model specs
$ vim spec/models/pubs_spec.rb

before(:each) do
  @pubs = 10.of { Pub.generate }
end


$ vim spec/spec_fixtures.rb
require 'dm-sweatshop'

Pub.fixture do
  {
    :name => ( name = %w[John Jane Jerry Justin][rand(4)] + quot;'s Pubquot;),
    :price => (1..30).to_a[rand(30)],
    :address => quot;#{(40..166).to_a[rand(126)]} Spring quot; + %w[Street Road Avenue][rand(3)],
    :url => quot;http://#{name.gsub(/W/, '').downcase}.com/quot;
  }
end




 model specs
run specs
$ rake spec:models




 run specs
$ rake spec:models

1)
NameError in 'Pub should have name, address, price'
address= is not a public property

2)
NameError in 'Pub should handle different url formats'
address= is not a public property

3)
NameError in 'Pub should consistently format + store urls'
address= is not a public property

Finished in 0.252169 seconds

3 examples, 3 failures




  run specs
define properties
$ vim app/models/pub.rb




define properties
$ vim app/models/pub.rb

class Pub
  include DataMapper::Resource

  property   :id, Serial
  property   :name, String, :nullable => false
  property   :address, String, :nullable => false
  property   :price, BigDecimal, :nullable => false
  property   :url, String




define properties
$ vim app/models/pub.rb

  ...

  def url=(string)
    string = quot;http://#{string}quot; unless string =~ /^http://.+//
    string += '/' unless string =~ //$/
    @url = string
  end

end




custom setter
run specs
$ rake spec:models




 run specs
$ rake spec:models

Finished in 0.488351 seconds

3 examples, 0 failures




  run specs              win!
request specs
$ vim spec/requests/pubs_spec.rb




request specs
$ vim spec/requests/pubs_spec.rb

...

it quot;contains a list   of cheapest pubsquot; do
   @response.should   have_xpath(quot;//div[@id=’cheapest’]quot;)
   @response.should   have_xpath(quot;//div[@id=’cheapest’]//table//tr//td[@class='name']quot;)
   @response.should   have_xpath(quot;//div[@id=’cheapest’]//table//tr//td[@class='address']quot;)
   @response.should   have_xpath(quot;//div[@id=’cheapest’]//table//tr//td[contains(@class,'price')]quot;)
end




request specs
run specs
$ rake spec:request




run specs
$ rake spec:request

Pending:
resource(:pubs) GET has a list of pubs (TODO)
  Called from ./spec/requests/pubs_spec.rb:37

1)
'resource(:pubs) GET contains a list cheapest pubs' FAILED
expected following text to match xpath //div[@id='cheapest']
./spec/requests/pubs_spec.rb:26:

Finished in 0.411139 seconds

10 examples, 1 failure, 1 pending




run specs
build partial
$ vim app/views/pubs/index.html.haml




build partial
$ vim app/views/pubs/index.html.haml
%h3 Nearest
%h3 Cheapest
%div#cheapest
  = partial quot;cheapestquot;




build partial
$ vim app/views/pubs/index.html.haml
%h3 Nearest
%h3 Cheapest
%div#cheapest
  = partial quot;cheapestquot;



$ vim app/views/pubs/_cheapest.html.haml




build partial
$ vim app/views/pubs/index.html.haml
%h3 Nearest
%h3 Cheapest
%div#cheapest
  = partial quot;cheapestquot;



$ vim app/views/pubs/_cheapest.html.haml
%table
  - @pubs.each_with_index do |pub, index|
    %tr
       %td.name=    link_to pub.name, pub.url
       %td.address= pub.address
       %td{:class => quot;price cheapest-#{index}quot;}
         = '$' + sprintf(quot;%.2fquot;, pub.price)


build partial
run specs
$ rake spec:request




run specs
$ rake spec:request

Pending:
resource(:pubs) GET has a list of pubs (TODO)
  Called from ./spec/requests/pubs_spec.rb:37

Finished in 0.854704 seconds

10 examples, 0 failures, 1 pending




run specs
nearest
$ vim app/views/pubs/index.html.haml




nearest
$ vim app/views/pubs/index.html.haml
%h3 Nearest
%div#nearest
  = partial quot;nearestquot;
%h3 Cheapest
%div#cheapest
  = partial quot;cheapestquot;




nearest
$ vim app/views/pubs/index.html.haml
%h3 Nearest
%div#nearest
  = partial quot;nearestquot;
%h3 Cheapest
%div#cheapest
  = partial quot;cheapestquot;

$ vim app/views/pubs/_nearest.html.haml




nearest
$ vim app/views/pubs/index.html.haml
%h3 Nearest
%div#nearest
  = partial quot;nearestquot;
%h3 Cheapest
%div#cheapest
  = partial quot;cheapestquot;

$ vim app/views/pubs/_nearest.html.haml
%div#map{:style => quot;width: 800px; height: 600px; margin: auto;quot;}




nearest
global layout
$ vim app/views/layout/application.html.erb




global layout
$ vim app/views/layout/application.html.erb
 <%= js_include_tag 'mootools' %>
 <%= js_include_tag 'SimpleTabs' %>
 <%= js_include_tag 'application' %>
 <script src=quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=
              <%= Merb.config.gmaps_api_key %>quot; type=quot;text/javascriptquot;></script>




global layout
$ vim app/views/layout/application.html.erb
 <%= js_include_tag 'mootools' %>
 <%= js_include_tag 'SimpleTabs' %>
 <%= js_include_tag 'application' %>
 <script src=quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=
              <%= Merb.config.gmaps_api_key %>quot; type=quot;text/javascriptquot;></script>




$ vim config/environments/development.rb

 c[:gmaps_api_key] = quot;fooquot;




api key
$ vim app/views/layout/application.html.erb
 <%= js_include_tag 'mootools' %>
 <%= js_include_tag 'SimpleTabs' %>
 <%= js_include_tag 'application' %>
 <script src=quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=
              <%= Merb.config.gmaps_api_key %>quot; type=quot;text/javascriptquot;></script>




$ vim config/environments/production.rb

c[:gmaps_api_key] = quot;barquot;




production api key
$ vim public/javascripts/application.js
window.addEvent('domready', function() {

});




nearest
$ vim public/javascripts/application.js
window.addEvent('domready', function() {

  if (GBrowserIsCompatible()) {
    var map = new GMap2($(quot;mapquot;));
    map.enableScrollWheelZoom();
    map.setCenter(new GLatLng(-33.86336, 151.207151), 12);
    var geocoder = new GClientGeocoder();

      /* geocode top-ten addresses */
      $$('div#cheapest tr').each( function(element) {
        showAddress(map, geocoder, element);
      });
  }

});




dash o’ javascript
$ vim public/javascripts/application.js
function showAddress(map, geocoder, element) {
  var name = element.getElements('td.name a').get('html');
  var address = element.getChildren('td.address').get('html');
  var price = element.getElements('td.price').get('html');
  var link = element.getElements('td.name a').get('href');

    geocoder.getLatLng(address, function(point) {
      if (point) {
        var marker = new GMarker(point);
         marker.bindInfoWindowHtml(quot;<h4>quot; + name + quot;</h4>quot; + ... );
         map.addOverlay(marker);
      }
    });
}




custom geocoder
some stylesheet foo
slices

    freezing

param-protection

  action-args
operations
monitoring
collectd
lightweight
 statistics
collection
 daemon
lightweight
 statistics
collection
 daemon
LoadPlugin   cpu
LoadPlugin   df
LoadPlugin   disk
LoadPlugin   interface
LoadPlugin   load
LoadPlugin   memory
LoadPlugin   network
LoadPlugin   processes
LoadPlugin   rrdtool
LoadPlugin   socket
LoadPlugin   swap
LoadPlugin   users

...
<Plugin df>
  MountPoint quot;/quot;
</Plugin>

<Plugin interface>
  Interface quot;eth0quot;
  Interface quot;eth1quot;
</Plugin>

...
<Plugin rrdtool>
  DataDir      quot;/var/lib/collectd/rrdquot;
  CacheTimeout 180
  CacheFlush   7200
</Plugin>

<Plugin network>
  Server quot;my.monitoring.server.netquot;
# Port    25826
</Plugin>

...
<Plugin processes>
  Process      quot;rubyquot;
# Process      quot;mysqldquot;
</Plugin>

...
eek!
collectd-nagios
$ /usr/bin/collectd-nagios 
    -s /var/run/collectd/socket 
    -n cpu-0/cpu-idle 
    -H my.server.com 
    -w 40: -c 10:

0 critical, 1 warning, 0 okay | value=34.000000;;;;


$ /usr/bin/collectd-nagios 
    -s /var/run/collectd/socket 
    -n df/df-root -H my.server.com 
    -d free -c 314572800: -w 524288000:

0 critical, 0 warning, 1 okay |free=924288000.0;;;;
0   good
1   bad
2   ugly
$ ls /var/lib/collectd/rrd/my.server.com
cpu-0       cpu-1 df    disk-sda
disk-sda1   interface   load
memory      swap        users
apache          apcups      apple sensors
    ascent         battery           cpu
   cpufreq           csv             df
     disk            dns            email
   entropy           exec         filecount
   hddtemp        interface       iptables
     ipmi            ipvs           irqs
   libvirt           load          logfile
    mbmon         memcached        memory
  multimeter        mysql          netlink
   network           nfs            nginx
notify_desktop   notify_email       ntpd
     nut           onewire          perl
     ping         postgresql      powerdns
  processes        rrdtool         sensors
    serial           snmp           swap
    syslog           tail           tape
   tcpconns       teamspeak2       thermal
   unixsock         users           uuid
     vmem          vserver        wireless
apache          apcups      apple sensors
    ascent         battery           cpu
   cpufreq           csv             df
     disk            dns            email
   entropy           exec         filecount
   hddtemp        interface       iptables
     ipmi            ipvs           irqs
   libvirt           load          logfile
    mbmon         memcached        memory
  multimeter        mysql          netlink
   network           nfs            nginx
notify_desktop   notify_email       ntpd
     nut           onewire          perl
     ping         postgresql      powerdns
  processes        rrdtool         sensors
    serial           snmp           swap
    syslog           tail           tape
   tcpconns       teamspeak2       thermal
   unixsock         users           uuid
     vmem          vserver        wireless
configuration
management
Puppet




language => client/server => library
manifests
types
classes
nodes
manifests => describe
types
classes
nodes
manifests
types     => manage
classes
nodes
package { apache2:
    ensure => present
}
package { apache2:
    ensure => present
}

file { quot;/etc/apache2/apache2.confquot;,
    content => template(quot;/etc/puppet/
    config/classes/httpd_server/
    httpd.conf.erbquot;),
    mode => 644
}
package { apache2:
    ensure => present
}

file { quot;/etc/apache2/apache2.confquot;,
    content => template(quot;/etc/puppet/
    config/classes/httpd_server/
    httpd.conf.erbquot;),
    mode => 644
}

service { apache2:
    ensure => running,
    subscribe => File[quot;/etc/apache2/
    apache2.confquot;]
}
manifests
types     => manage
classes
nodes
manifests
types
classes => group
nodes
package { apache2:
  ensure => present
}

# ...
class apache2 {

    package { apache2:
      ensure => present
    }

    # ...

}
class passenger inherits apache2 {

    package { libapache2-mod-passenger:
      ensure => present
    }

    # ...

}
define apache2 ($port) {

    package { apache2:
      ensure => present
    }

    # ...

}
manifests
types
classes => group
nodes
manifests
types
classes
nodes     => apply
node quot;srv01.skippy.comquot; {
    include passenger
}
node quot;srv01.skippy.comquot; {
    include passenger
}
node quot;srv01.skippy.comquot; {
    include passenger
}

node quot;server02.skippy.comquot; {
    include passenger
}

node quot;server03.skippy.comquot; {
    include passenger
}
node quot;merbnodequot; {
    include passenger
}

node quot;server01.skippy.comquot; inherits passenger {}

node quot;server02.skippy.comquot; inherits passenger {}

node quot;server03.skippy.comquot; {
    include customisation
}
versionable
infrastructure
versionable
infrastructure
    (for free)
$ cd skippy.puppet.lindsay
$ git init
# puppet magic happens
$ git push
# puppetd --test --debug
resources
getting real


seth godin

wiki.merbivore.com
Thank you!
 (and questions)

Más contenido relacionado

La actualidad más candente

Big Design Conference: CSS3
Big Design Conference: CSS3 Big Design Conference: CSS3
Big Design Conference: CSS3
Wynn Netherland
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet ModulesPuppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
Tammy Hart
 

La actualidad más candente (19)

Custom post-framworks
Custom post-framworksCustom post-framworks
Custom post-framworks
 
Workshop 6: Designer tools
Workshop 6: Designer toolsWorkshop 6: Designer tools
Workshop 6: Designer tools
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephp
 
Accelerated Stylesheets
Accelerated StylesheetsAccelerated Stylesheets
Accelerated Stylesheets
 
Big Design Conference: CSS3
Big Design Conference: CSS3 Big Design Conference: CSS3
Big Design Conference: CSS3
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
RESTful web services
RESTful web servicesRESTful web services
RESTful web services
 
An introduction to Rex - FLOSS UK DevOps York 2015
An introduction to Rex - FLOSS UK DevOps York 2015An introduction to Rex - FLOSS UK DevOps York 2015
An introduction to Rex - FLOSS UK DevOps York 2015
 
Image Manipulation in WordPress 3.5 - WordCamp Phoenix 2013
Image Manipulation in WordPress 3.5 - WordCamp Phoenix 2013Image Manipulation in WordPress 3.5 - WordCamp Phoenix 2013
Image Manipulation in WordPress 3.5 - WordCamp Phoenix 2013
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet ModulesPuppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
Contributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonContributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter Wilson
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Rails2 Pr
Rails2 PrRails2 Pr
Rails2 Pr
 

Destacado

Destacado (6)

Latency: The Silent Monitoring System Killer
Latency: The Silent Monitoring System KillerLatency: The Silent Monitoring System Killer
Latency: The Silent Monitoring System Killer
 
AA261: DevOps lessons in collaborative maintenance
AA261: DevOps lessons in collaborative maintenanceAA261: DevOps lessons in collaborative maintenance
AA261: DevOps lessons in collaborative maintenance
 
Islands: Puppet at Bulletproof Networks
Islands: Puppet at Bulletproof NetworksIslands: Puppet at Bulletproof Networks
Islands: Puppet at Bulletproof Networks
 
Escalating complexity: DevOps learnings from Air France 447
Escalating complexity: DevOps learnings from Air France 447Escalating complexity: DevOps learnings from Air France 447
Escalating complexity: DevOps learnings from Air France 447
 
Load testing with Blitz
Load testing with BlitzLoad testing with Blitz
Load testing with Blitz
 
Behaviour Driven Monitoring with cucumber-nagios
Behaviour Driven Monitoring with cucumber-nagiosBehaviour Driven Monitoring with cucumber-nagios
Behaviour Driven Monitoring with cucumber-nagios
 

Similar a Your own (little) gem: building an online business with Ruby

Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Jesse Vincent
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
railsconf
 
Socket applications
Socket applicationsSocket applications
Socket applications
João Moura
 
浜松Rails3道場 其の四 View編
浜松Rails3道場 其の四 View編浜松Rails3道場 其の四 View編
浜松Rails3道場 其の四 View編
Masakuni Kato
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
elliando dias
 

Similar a Your own (little) gem: building an online business with Ruby (20)

Monitoring web application behaviour with cucumber-nagios
Monitoring web application behaviour with cucumber-nagiosMonitoring web application behaviour with cucumber-nagios
Monitoring web application behaviour with cucumber-nagios
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
 
When To Use Ruby On Rails
When To Use Ruby On RailsWhen To Use Ruby On Rails
When To Use Ruby On Rails
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
 
More Secrets of JavaScript Libraries
More Secrets of JavaScript LibrariesMore Secrets of JavaScript Libraries
More Secrets of JavaScript Libraries
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!
 
So you want to build a Facebook app
So you want to build a Facebook appSo you want to build a Facebook app
So you want to build a Facebook app
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Rails 2.3 and Rack - NHRuby Feb 2009
Rails 2.3 and Rack - NHRuby Feb 2009Rails 2.3 and Rack - NHRuby Feb 2009
Rails 2.3 and Rack - NHRuby Feb 2009
 
浜松Rails3道場 其の四 View編
浜松Rails3道場 其の四 View編浜松Rails3道場 其の四 View編
浜松Rails3道場 其の四 View編
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
 
URL Mapping, with and without mod_rewrite
URL Mapping, with and without mod_rewriteURL Mapping, with and without mod_rewrite
URL Mapping, with and without mod_rewrite
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Ruby Isn't Just About Rails
Ruby Isn't Just About RailsRuby Isn't Just About Rails
Ruby Isn't Just About Rails
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 

Your own (little) gem: building an online business with Ruby