Internetbureau Holder

HollandOnRails jaaroverzicht 2009

Chiel Wester wo 06 jan 10

Het nieuwe jaar is inmiddels alweer 6 dagen begonnen. Hoog tijd om terug te blikken op het afgelopen jaar!

Tweeduizend-negen begon met de mededeling dat er een merge zou gaan plaatsvinden tussen RubyOnRails en Merb. Deze geheel nieuwe en verbeterde versie zal versie 3 worden. Na een jaar tijd is er nog geen eerste release van rails 3 geweest, maar is er (uiteraard) wel een werkende edge versie beschikbaar.

Eind januari werd Railsconf Europe 2009 geannuleerd. Reden was dat het evenement te weinig geld in het laatje bracht bij organisator O’Reilly.

In maart 2009 werd Rails 2.3 uitgebracht. Inmiddels zitten we op versie 2.3.5 waarbij de minor releases allemaal kleine bugfixes en enkele security fixes waren.

In oktober werd door ons de RubyEnRails conferentie voor de vierde keer georganiseerd. Dit jaar bestond de conferentie voor het eerst uit twee dagen. Er waren aansprekende sprekers aanwezig waaronder Yehuda Katz en Jeremy Kemper. Op dag 2 werd er bovendien een RubyEnRails Rumble gehouden en deze werd gewonnen door Kabisa.

Wat zal 2010 ons op RubyOnRails gebied gaan brengen? 2010 zal het jaar worden van Rails 3.0, de eerste jubileum-editie van de RubyEnRails-conferentie en wat ons betreft het jaar van BettyBlocks.

Eén ding zal in 2010 niet veranderen:

HollandOnRails is ook in 2010 weer een vaste waarde!

Gepost in hor |  0 reacties

Massa toewijzing in Rails

Stephan Kaag di 05 jan 10

De gevolgen voor de veiligheid van een applicatie ten gevolge van mass assignment in Rails zijn al vanaf de eerste versie gedocumenteerd. Toch blijken lang niet alle applicaties hier goed mee om te gaan.

Mass assignment

@user = User.new(params[:user])

In de regel hierboven wordt mass assignment gebruikt om een nieuwe User instantie aan te maken en direct alle (door de browser verstuurde) attributen in te stellen.
Als er geen extra maatregelen worden genomen kan iemand met kwaad in de zin zijn eigen parameters meesturen en deze dus direct (automagisch) laten instellen. Stel dat een er een kolom is_admin bestaat, dan is in die normaal gesproken direct beïnvloedbaar voor misbruik met alle mogelijke gevolgen van dien.

has_many :blog_posts

Het zijn niet alleen database kolommen die op deze manier misbruikt kunnen worden. Stel je voor dat de bovenstaande regel ook in het user-model aanwezig is. Doordat has_many toestaat om direct de id’s via mass assignment in te stellen kan een kwaadwillende user[blog_post_ids][] meesturen om toegang te krijgen tot iemand anders’ blog-posts!

Beveiliging

Rails biedt de class method attr_accessible aan die een whitelist- oplossing gebruikt voor beveiliging. Als je attr_accessible gebruikt kan je de attributen aangeven die je via mass-assignment instelbaar wilt maken en alle andere attributen zullen beveiligd worden.

Gepost in hor |  1 reactie

Gem-this

Stephan Kaag di 22 dec 09

Traditionele Rails plugins worden meer en meer vervangen door gems. Gems hebben dan ook voordelen boven plugins. Denk aan distributie (rubygems), versiebeheer en dependencies.

Met de gem (jawel) gem-this wordt het maken van een rubygem je makkelijker gemaakt. Door na installatie in een source-map gem this uit te voeren wordt er een Rakefile voor je aangemaakt.

$ rake -T
rake clean                   # Clear out RDoc and generated packages
rake clobber_package         # Remove package products
rake clobber_rdoc            # Remove rdoc products
rake gem                     # Build the gem file gem-this-0.1.0.gem
rake package                 # Build all the packages
rake rdoc                    # Build the rdoc HTML Files
rake repackage               # Force a rebuild of the package files
rake rerdoc                  # Force a rebuild of the RDOC files
rake rubyforge:release       # Release gem and RDoc documentation to RubyForge
rake rubyforge:release:docs  # Publish RDoc to RubyForge.

Je kan nu direct een gem bakken door rake package te vuren maar waarschijnlijk wil je nog wel zaken aanpassen aan je Rakefile of .gemspec. Gem-this is dan ook enkel bedoeld om je de basis van het gem-builden uit te handen te nemen.

Gepost in hor |  0 reacties

Variabelen gebruiken in Wireframes

Gawin Dapper di 22 dec 09

Vorige keer hebben we het maken van Wireframes met OmniGraffle besproken. Als uitbreiding hierop zullen we vandaag het invoegen van variablen bespreken.

OmniGraffle Variables

In OmniGraffle is het mogelijk om variablen in tekstvelden te gebruiken welke automatisch aangepast worden. De volgende variabelen zijn beschikbaar:

  • Canvas Name, <%Canvas%>
  • Layer Name, <%Layer%>
  • Document, <%Document%>
  • Current Date, <%Date%>
  • Document Creation Date, <%CreationDate%>
  • Document Modification Date, <%ModificationDate%>
  • Creator, <%Creator%>
  • Modifier, <%Modifier%>
  • Page Number, <%#%>
  • Total Pages, <%TotalPages%>
  • X Position, <%X%>
  • Y Position, <%Y%>
  • Width, <%Width%>
  • Height, <%Height%>
  • Line Length, <%Length%>

Deze variablen zijn tevens te vinden via het menu Edit > Insert Variable.

Tekstvelden

De bovenstaande variabelen zijn vervolgens te gebruiken in elk tekstveld (inclusief opmaak).

OmniGraffle Variables

Hierbij is de Line Length een vreemde eend in de bijt, aangezien deze de lengte van een lijn in een lijn label laat zien.

OmniGraffle Variable Line Length

Gebruik in Wireframes

In de Wireframes kunnen we deze nu gebruiken om extra informatie op de pagina weer te geven. Dit kan bijvoorbeeld erg prettig zijn bij het maken van print-outs.

De Canvas Name weergeven in de header:
Wireframe Header, Date

De datum waarop de laatste wijzigingen zijn doorgevoerd weergeven:
Wireframe Header, Canvas Name

Het eind resultaat:
Wireframe Header, Original

Bron bestanden:

Gepost in  |  0 reacties

Is MongoDB hetgeen voor databases wat Rails was voor frameworks?

Paul Engel di 22 dec 09

John van Railstips heeft onlangs een artikel gepost met een gewaagde stelling:

MongoDB is hetgeen voor databases wat Rails was voor frameworks.

Hij heeft namelijk Harmony, een website gedreven op MySQL, omgezet naar Mongo en is erg te spreken over deze migratie. John onderbouwt zijn stelling met de volgende punten:

  • Migrations are Dead
  • Single Collection Inheritance Gone Wild
  • Array Keys
  • Hash Keys
  • Embedding Custom Objects
  • Incrementing and Decrementing
  • Files, aka GridFS

Geïnteresseerd? Lees dan het volledige artikel.

Gepost in hor |  0 reacties

Factory Girl - Een Fixture vervanging voor Rails

Michael Koper do 17 dec 09

Ik denk dat iedereen die zich wel eens met testen bezig gehouden heeft wel problemen heeft gehad met het gebruik van Fixtures. Veel extra data in verschillende files, moeilijk met dependencies en veel conflicten als je vele fixtures hebt. Factory Girl moet deze problemen oplossen!

Factory Girl is een model generator die test data voor je genereerd. Het is zo gemaakt dat je je Factories kan hergebruiken dus bij de meeste models hoef je maar 1 Factory te hebben. Factory Girl is er al een tijdje, maar voor degene die het nog niet weten, hier een korte uitleg hoe Factory Girl werkt.

Factories gebruik je alleen tijdens het testen dus voor de installatie kan je de volgende code in test.rb zetten.

config.gem "factory_girl", :source => "http://gemcutter.org"

Maak daarna een nieuwe file bijv factories.rb in je spec directory of natuurlijk een directory naar keuze. Zet daarna de volgende code in je spec_helper.rb.
require File.dirname(__FILE__) + /factories""

Hierna is het de bedoeling dat de Factories gedefineerd worden. Hieronder een voorbeeldje voor een User Factory.

Factory.define :user, :class => User do |u|
  f.sequence(:login) { |n| "piet{n}" }
  f.name "Piet"
  f.password "geheim"
  f.password_confirmation { |p| p.password }
  f.sequence(:email) { |e| "info#{e}@domein.nl" }
  f.activation_code { User.generate_activation_code }
  f.admin false
end

De sequence methode is bedoeld voor data die uniek moet zijn. Als er meerdere Factories worden gegenereerd worden de login namen: piet1, piet2, piet3 enz. Zelfde geldt voor de emails. De password_confirmation wordt automatisch hetzelfde als password. Ook kunnen methodes gebruikt worden om de attributen te vullen, zie bij het veldje activation_code. Als hier een fixture gebruikt zou worden dan zou het ongeveer zo zijn:

user: piet
  name: Piet
  password: 5f4dcc3b5aa765d61d8327deb882cf99
  salt: ceb20772e0c9d240c75eb26b0e37abee
  etc etc

Je zou dus voor elke user een aparte fixture moeten maken en zoals je kan zien zijn de password velden onleesbaar en zijn daarom je tests minder leesbaar. Hoe test je bijvoorbeeld of de password goed of niet goed is? Je zou dan bijv in de comments moeten zetten wat het password daadwerkelijk is.

Ook zijn associaties mogelijk, zie het volgend voorbeeld.

Factory.define :post do |f|
  f.subject "Factory Girl is awesome!"
  f.author {|author| author.association(:user, :admin => true) }
end

Hier heeft de post een associatie met een admin. Er zijn nog vele mogelijkheden zoals Inheritance, Callbacks (after build, after create). Hier een voorbeeldje hoe je Factories kan gebruiken in RSpec.

describe User do
  it "should authenticate with the right user and password"
    user = Factory(:user, :login => "piet", :password => "geheim")
    User.authenticate("piet", "geheim").should == user
  end
	
  it "should not authenticate with wrong password"
    user = Factory(:user, :login => "piet", :password => "geheim")	
    User.authenticate("piet", "verkeerd").should be_nil
  end
end

Zoals je kan zien wordt hierboven de zelfde Factory 2 keer met andere data gebruikt. Als je een Factory alleen wil initialeseren kan je Factory.build(:user) gebruiken in plaats van Factory(:user).

Gepost in hor |  1 reactie

Acts As State Machine

Chris Brandhorst di 15 dec 09

Ik loop regelmatig tegen modellen aan die een status / state hebben die in het model moet worden gedefinieerd.

Hier is een erg handige rubygem voor: Acts As State Machine
Deze gem maakt van iedere Class waar je AASM in include, een state machine.

Een voorbeeld:

require 'rubygems'
require 'aasm'

class Conversation
  include AASM
  
  # Can also be a Proc
  aasm_initial_state :unread
  
  # State definitions and enter and/or exit callbacks
  aasm_state :unread
  aasm_state :read, :enter => :send_read_confirmation
  aasm_state :closed
  aasm_state :ignored
  
  # Event transitions with optional guards
  aasm_event :view do
    transitions :to => :read, :from => [:unread]
  end
  aasm_event :close do
    transitions :to => :closed, :from => [:read, :unread]
  end
  aasm_event :ignore do
    transitions :to => :ignored, :from => [:unread], :guard => :sender_is_a_douchebag
  end
  
  private
  
  def send_read_confirmation
    puts "Read confirmation sent"
  end
  
  def sender_is_a_douchebag
    false
  end
  
end

c = Conversation.new
# initial state is 'unread'
c.ignore
# sender is not a douchebag, so no ignoring
# state is still 'unread'
c.view
# now, state is 'read', confirmation is sent
c.close
# now, state is 'closed'

Voor ieder van de vier states kan opgegeven worden welke methoden aan moeten worden geroepen bij het binnenkomen van die state (enter) en het verlaten van die state (exit). Ook kan een initiële state worden ingesteld.

Daarnaast kan je transities (events) definiëren, die bepaalde state changes (en de daaraan hangende callbacks) in gang zetten. Transities worden gedefiniëerd door te zeggen wat de doel-state en wat de mogelijke start-states zijn. Ook kan een guard callback worden opgegeven waarmee verdere restricties op de transities kunnen worden gelegd.

Ten slotte wordt ook support geleverd voor het toepassen van dit geheel in Rails door middel van het opgeven van de kolomnaam waar de state in moet worden opgeslagen:

aasm_column :column_name

De huidige state kan op worden gevraagd door middel van:

c.aasm_current_state

Dat laatste is een wat lange methode naam, maar je kan er altijd nog zelf een wrapper omheen maken. Maar als je de state machine goed implementeerd, hoef je van buiten niet het state-attribuut te hoeven lezen. Je kan namelijk altijd controleren of een instantie in een bepaalde state is dmv bijvoorbeeld:

c.ignored?

Dit geeft true terug als de huidige state ‘ignored’ is.

Gepost in hor |  0 reacties

Ruby en Rails 2009 video's

Johan Vermeulen di 15 dec 09

Ze staan al even op de Ruby en Rails site, maar we hadden er hier nog niet over geblogd, de video’s van de presentatie staan online:

  1. ReR09 – Bart ten Brinke – To Measure is to Know
  2. ReR09 – Bart Zonneveld & Sjoerd Tieleman
  3. ReR09 – Dax Huiberts – DRYing up your views
  4. ReR09 – Dirk-jan Bussink – Datamapper
  5. ReR09 – Yehuda Katz, Merging Rails
  6. ReR09 – Wes Oldenbeuving – DRY Cross-Browser CSS With SASS
  7. ReR09 – Stijn Mathysen – JQuery on Rails
  8. ReR09 – Norbert Crombach – EventMachine
  9. ReR09 – Michael Dirolf – MongoDB
  10. ReR09 – Justin Halsall – DSLs in the Front End
  11. ReR09 – Dmitry Jemerov – Using RubyMine for Rails
  12. ReR09 – Jonathan Weiss – Rails Security
  13. ReR09 – Jeremy Kemper – Rails 3
  14. ReR09 – Eloy Duran – MacRuby
  15. ReR09 – Edwin Vlieg – Advanced Testing
  16. ReR09 – Julian Fisher – Evolutionary Algorithms
  17. ReR09 – Julio Javier Cichelli – The Rubyists.EU Initiative

Gepost in hor |  0 reacties

Gebruik je live data in je ontwikkelomgeving met Reflection

Dax Huiberts ma 14 dec 09

Al sinds ik ben begonnen met Rails ontwikkeling heb ik de behoefte gehad om regelmatig live data, zoals de data in je database en plaatjes die zijn geupload, van de productieomgeving in mijn ontwikkelomgeving te hebben. Voorheen deed ik dat met een paar capistrano tasks, maar in onze huidige omgeving gebruiken we nu webistrano en is dit dus geen mogelijkheid meer.

Tegenwoordig is er reflection, een tool die speciaal hiervoor bedoeld is. Alleen heeft reflection een heel groot voordeel tegenover een standaardoplossing zoals ik die had met capistrano. Reflection slaat namelijk alles op in een git repository, wat betekent dat je alleen maar de nieuwe data hoeft binnen te halen. Zeker als je database dumps tientallen tot wel honderden MBs oploopt zal dit een enorm voordeel opleveren met de tijd dat het duurt totdat je een database dump binnen hebt.

Met een cronjob op de server kan je gemakkelijk iedere nacht de data in een git repository krijgen met behulp van het volgende commando:

$ reflection  --stash \
              --directory /path/to/your/assets \
              --repository git@your-shared-repository.git \
              --rails /rails/root \
              --rails-env production

En dan op je development machine kan je deze data weer gemakkelijk toepassen met het commando:

$ reflection  --apply \
              --directory /path/to/your/assets \
              --repository git@your-shared-repository.git \
              --rails /rails/root \
              --rails-env development

Lees de readme voor meer informatie om ook gemakkelijk de instellingen in een configuratie file te zetten en voor andere handige tips.

Gepost in hor |  0 reacties

MongoDB 1.2.0 vrij gegeven

Johan Vermeulen vr 11 dec 09

De heren van MongoDB hebben een nieuwe versie vrij gegeven, versie 1.2.0.

MongoDB is een document geörienteerde database zonder schema.

Enkele wijzigingen sinds 1.0:
- More than 10 indexes
- Much faster index creation
- Map/Reduce
- Stored JavaScript functions

Video uitleg
Download MongoDB
Changelog
Release notes

Gepost in hor |  0 reacties

Welcome to Holland On Rails

This weblog is the official Ruby techblog from the guys at Holder, a Ruby development company. Holder is also the company behind the RubyAndRails Europe Conference in Amsterdam.

Recente Jobs


Bekijk alle jobs »»

Gereedschapskist

Onmisbare tools voor
iedere developer!
Ruby On Rails
Framework voor de web 2.0 developer. Eindelijk vooruitgang!
TextMate
Editor for true pro's
Typ, tab, top :-)
Nee, niet voor Win.
Made On A Mac
En nou is het over met die saaie grijze Windows bak van je!

Auteurs op deze site

Chris Obdam

'Less is more' evangelist, past dit ook dagelijks toe op zijn tandenborstel.

Chiel Wester

Snelheidswonder op Ruby wielen. Leuk om mee te pair-programmen ;-) Recommend Me

Stephan Kaag

Het eerste Rails coreteam- member uit Nederland? Rails evangelist van het eerste uur.

Paul Engel

Én Rails programmeren én interfaces designen? Je zou hem superman kunnen noemen..

Dax Huiberts

Official Zip-Programmer, skinny code is helemaal zijn ding. Haalt meer code weg dan dat er bij komt.

Freek Monteban

Het nieuwste telg uit het Holland on Rails nest! Hij doet niets anders meer!

Johan Vermeulen

De stylesheet-koning uit de kop van Noord-Holland!