モデルのコールバックを使う
元記事はこちら
翻訳
Bad Smell
<% form_for @post do |f| %> <%= f.text_field :content %> <%= check_box_tag 'auto_tagging' %> <% end %> class PostsController < ApplicationController def create @post = Post.new(params[:post]) if params[:auto_tagging] == '1' @post.tags = AsiaSearch.generate_tags(@post.content) else @post.tags = "" end @post.save end end
上記の例では、ユーザーがauto_taggingチェックボックスをクリックしていた場合に、postの内容に従ってtagsを生成し、保存前にpostにtagsの値をセットします。モデルのコールバックを使えば、tagsの値をセットする処理をモデルに移動できます。
Refactor
class Post < ActiveRecord::Base attr_accessor :auto_tagging before_save :generate_tagging private def generate_taggings return unless auto_tagging == '1' self.tags = Asia.search(self.content) end end <% form_for @post do |f| %> <%= f.text_field :content %> <%= f.check_box :auto_tagging %> <% end %> class PostsController < ApplicationController def create @post = Post.new(params[:post]) @post.save end end
上記の通り、before_saveコールバックで、ユーザーがauto_taggingをクリックしていた場合にtagsを生成して、値をセットするPostモデルのgenerate_taggingを作成しました。これでPostsControllerでモデルロジックを気にする必要がなくなりました。
感想
before_save
うまく使えるとコントローラーのロジックをぐっと減らせるので便利。