-
Notifications
You must be signed in to change notification settings - Fork 12
Merb to Rails cheatsheet
In Merb, dependencies are handled by built-in dependency-checker tasks, along with the thor command-line utility.
In Rails 3, gem dependencies are handled by the ‘bundler’ gem. This should be the only gem you need to install manually to your system gems:
$ sudo gem install bundler
Then, from the application directory, you can run:
$ bundle install
which (assuming your system gem directory is not writeable by your user) will install the necessary gems (the ‘bundle’) for the app in ~/.bundle.
Rails will preload the app’s bundle environment automatically, but if you want to load the app’s bundle environment in your shell (e.g. in order to run the specs), you can use the ‘bundle exec’ command, e.g.:
$ bundle exec rake spec
Or you can spawn an entire subshell in which the gem bundle is accessible, e.g.:
$ bundle exec bash
Merb | Rails | |
---|---|---|
Server |
$ bin/merb
|
$ bundle exec rails server
|
Console |
$ bin/merb -i
|
$ bundle exec rails
|
You can generate files for models, controllers, mailers, etc., using the rails generate
command, e.g.:
$ bundle exec rails generate model Person name:string email:string
For usage documentation, run
$ bundle exec rails generate
- Rails methods that take a URL parameter expect one of:
- a string containing the URL;
- a hash including at least
:controller
and:action
; or - a
_path
method (AKA a ‘named route’).
- If you just want to generate a URL as a string, you can use the
url_for
method, or a named route method, e.g.:
url_for(:controller => 'induction', :action => 'founding_meeting') members_path(@member) proposals_url(@proposal)
Merb | Rails | |
---|---|---|
Redirects, URLs |
redirect(url(:controller => 'induction', :action => 'founding_meeting))
|
redirect_to(:controller => 'induction', :action => 'founding_meeting)
|
redirect(resource(@members))
|
redirect_to(members_path)
|
|
redirect(resource(@member))
|
redirect_to(member_path(@member))
|
|
Flash messages |
redirect(url(...), :message => {:error => "You must fill in the objectives."})
|
redirect_to_(..., :flash => {:error => "You must fill in the objectives."})
|
message[:error] = "You must fill in the objectives."
|
flash[:error] = "You must fill in the objectives."
|
- Explicit call to ‘render’ at the end of the action is not required in Rails; action will render its own template by default unless a ‘redirect_to’ or ‘render’ is called.
Merb | Rails | |
---|---|---|
Before filters |
before :ensure_member_inducted
|
before_filter :ensure_member_inducted
|
skip_before :ensure_organisation_active
|
skip_before_filter :ensure_organisation_active
|
|
Halting the controller in a before filter requires :halt to be thrown:throw :halt, redirect(url(:controller => 'induction', :action => 'founder))
|
Halting the controller in a before filter just requires redirect_to or a render to be called:redirect_to(:controller => 'induction', :action => 'founder')
|
|
Responding to requested data format |
|
|
ActiveRecord in Rails 3 uses a relational delayed-query syntax, so you can build up a query like this:
@decisions = Decision.where(["id = ?", id]).order("name ASC")
which will return a ‘relation’. The DB query is only actually executed when you try to access members of that relation:
@decisions.each{|decision| ...}
@decisions.first
@decisions.count
This also applies to our custom ‘scopes’, so you can do things like:
@proposals = Proposal.currently_open.limit(5).order('id DESC')
WHERE clauses are given as SQL snippets into which variables are interpolated (ActiveRecord does the escaping for you). There are a couple of syntaxes for this:
Proposal.where(['name = ? AND id > ?', the_name, the_id])
Proposal.where(['name = :name AND id => :id, {:name => the_name, :id => the_id}])
There is also a simplified hash syntax for WHERE clauses that only contain ‘=’ comparisons (i.e. no ‘>’, ‘<’, ‘!=’, etc.):
Proposal.where(:name => the_name, :id => the_id)
Merb | Rails |
---|---|
@decision = Decision.get!(id)
|
@decision = Decision.find(id)
|
@decisions = Decision.all(:limit => 5, :order => [:id.desc])
|
@decisions = Decision.order("id DESC").limit(5)
|
Clause.all(:name => name, :ended_at => nil, :id.not => self.id).update!(:ended_at => Time.now.utc)
|
Clause.where(["name = ? AND ended_at IS NULL and id != ?", name, self.id]).update_all(:ended_at => Time.now.utc)
|
Vote.first(:member_id => self.id, :proposal_id => proposal_id)
|
Vote.where(:member_id => self.id, :proposal_id => proposal_id).first
|
Vote.count(:proposal_id => self.id, :for => false)
|
Vote.where(:proposal_id => self.id, :for => false).count
|
In ActiveRecord, a model’s attributes are entirely defined by the database schema. To add or remove attributes, create a database migration (e.g. rails generate migration AddSurnameToMembers
), run it (rake db:migrate
), and the models will pick up the change.
Boolean attributes must be queried using the ‘?’ version of the method, otherwise the integer will not be coerced into a boolean value e.g.:
Merb/DataMapper: @proposal.accepted
Rails/ActiveRecord: @proposal.accepted?
Merb | Rails |
---|---|
has n, :votes
|
has_many :votes
|
has 1, :decision
|
has_one :decision
|
belongs_to :proposer, :class_name => 'Member', :child_key => [:proposer_member_id]
|
belongs_to :proposer, :class_name => 'Member', :foreign_key => 'proposer_member_id'
|
after :create, :send_email
|
after_create :send_email
|
validates_present :proposer_member_id
|
validates_presence_of :proposer_member_id
|
Merb | Rails |
---|---|
DecisionMailer.dispatch_and_deliver(:notify_new_decision, {}, {:member => @member, :decision => @decision})
|
DecisionMailer.notify_new_decision(:member => @member, :decision => @decision).deliver
|
- Strings that you build by yourself (i.e. not using the built-in helpers like
submit_tag
, etc.) are HTML-escaped by default. To output raw HTML, use theraw
helper.
Merb:
= form(:action => url(:controller => 'induction', :action => 'create_founding_meeting_details')) do
= text_field(:name => 'date', :value => @founding_meeting_date, :label => "Date")
= submit("Save details and move on")
Rails:
= form_tag(:controller => 'induction', :action => 'create_founding_meeting_details') do
= label_tag(:date)
= text_field_tag(:date, @founding_meeting_date)
= submit_tag("Save details and move on")
Merb:
= form_for(@founder, :action => url(:controller => 'induction', :action => 'create_founder')) do
= text_field :email, :label => "Email Address"
= submit "Save"
Rails:
= form_for(@founder, :url => {:controller => 'induction', :action => 'create_founder}) do |f|
= f.label :email, "Email Address"
= f.text_field :email
= submit_tag "Save"
Merb | Rails |
---|---|
= partial 'common/constitution', :allow_changes => false
|
= render :partial => 'shared/constitution', :locals => {:allow_changes => false}
|
@datetime.formatted(:long)
|
@datetime.to_s(:long)
|
time_to_go_in_words(proposal.end_date)
|
distance_of_time_in_words_to_now(proposal.end_date)
|
Merb:
@response = request('/one_click')
@response.should redirect_to(url(:controller => 'induction', :action => 'founding_meeting'))
Rails:
get('/one_click')
@response.should redirect_to(:controller => 'induction', :action => 'founding_meeting')
Merb:
@response = request(url(:controller=>'one_click',
:action=>'propose_voting_system_amendment'),
:method=>'POST', :params=>{:membership_voting_system=>'Veto'})
Rails:
post(url_for(:controller=>'one_click', :action=>'propose_voting_system_amendment'),
{:membership_voting_system=>'Veto'})
- User authentication is handled by new methods in Member, and MemberSessionsController.
Merb | Rails |
---|---|
session.user
|
current_user
|
Organisation.name
|
Organisation.organisation_name
|
Member.all.active
|
Member.active
|
Proposal.all_open
|
Proposal.currently_open
|
Proposal.all_failed
|
Proposal.failed
|
Merb | Rails |
---|---|
Merb.logger.info
|
Rails.logger.info
|
JSON.parse(json_string)
|
ActiveSupport::JSON.decode(json_string)
|