Essentail Rails Design Pattern

Write Good Rails Code

儲存之前、儲存之後需要 Do Something

在從前,在 Controller 裡面想要再 object 儲存之後 do_something,直觀的思路會是這樣:

1
2
3
4
5
6
7
8
class PostController
  def create
    @post = Post.new(params[:post])
    @post.save
    @post.do_something
    redirect_to posts_path
  end
end

但這樣的作法其實是不小問題的。

  • do_somehting 牽扯到 3rd party API,若 3rd party API 有問題則使用者完成這個 action 並返回 posts_path 的時間會很久
  • do_somehting 失敗可能會造成使用者無法 posts_path
  • controller 其實不太需要知道 model 儲存之後應該 do_somehting 的事,這應該是 model 的責任。

這些情境,Rails 提供了兩套機制解決:分別是 callbacks 與 Observer。

ActiveRecord “callbacks”

Rails 的 ActiveRecord 提供了相當方便的 callbacks,能讓開發者在寫 Controller 時,能夠寫出更加 DRY 的程式碼:

  • before_crearte
  • before_save
  • after_create
  • after_save …

上述程式碼可以被翻修成這樣:

1
2
3
4
5
6
7
class PostController < ApplicationController
  def create
    @post = Post.new(params[:post])
    @post.save
    redirect_to posts_path
  end
end
1
2
3
4
5
6
7
8
class Post < ActiveRecord::Base
  after_create :do_something

  protected

  def do_something
  end
end

Observer

或者是使用 ActiveRecord::Observer

1
2
3
4
5
6
7
class PostController < ApplicationController
  def create
    @post = Post.new(params[:post])
    @post.save
    redirect_to posts_path
  end
end
1
2
3
4
5
6
7
8
class PostObserver < ActiveRecord::Observer
  observ :post

  def after_create(post)
    do_something
  end

end
1
2
3
4
5
6
7
class Post < ActiveRecord::Base

  protected

  def do_something
  end
end

Comments