Skip to content

Rails CRUD with ActiveRecord

krisleech edited this page Oct 14, 2014 · 6 revisions

This shows a typical Rails CRUD controller.

NEW: You might also like Wisper-ActiveRecord

The model, models/bid.rb:

class Bid < ActiveRecord::Base
  include Wisper::Publisher

  validates :amount, :presence => true

  def commit(_attrs = nil)
    assign_attributes(_attrs) if _attrs.present?
    result = save
    if result
      broadcast(:bid_create_successful, self)
    else
      broadcast(:bid_create_failed, self)
    end
    result
  end
end

The listener, listeners/bid_listener.rb:

class BidListener
  def bid_create_successful(bid)
    # ...
  end
end

The controller, controllers/bids_controller.rb:

class BidsController < ApplicationController
  def new
    @bid = Bid.new
  end

  def create
    @bid = Bid.new(:amount => 40)
    @bid.subscribe(BidListener.new)
    @bid.on(:bid_create_successful) { redirect_to bid_path }
    @bid.on(:bid_create_failed)     { render :action => :new }
    @bid.commit
  end

  def edit
    @bid = Bid.find(params[:id])
  end

  def update
    @bid = Bid.find(params[:id])
    @bid.subscribe(BidListener.new)
    @bid.on(:bid_update_successful) { redirect_to bid_path }
    @bid.on(:bid_update_failed)     { render :action => :edit }
    @bid.commit(params[:bid])
  end
end

It is most likely that you might want to mix the commit method in to all ActiveRecord models by creating a module as such:

module Wisper::Commit
  def commit(_attrs = nil)
    assign_attributes(_attrs) if _attrs.present?
    result = save
    if result
      broadcast("#{self.class.model_name.parameterize}_create_successful", self)
    else
      broadcast("#{self.class.model_name.parameterize}_create_failed", self)
    end
    result
  end
end

ActiveRecord::Base.class_eval { include Wisper::Commit }

This could probably be wrapped up as a gem. See: https://github.com/krisleech/wisper-activerecord