RubyOnRails演習 (1)

2013-04-23T00:00:00+00:00 Ruby Rails

色々演習的な事やってみようかと、とりあえずCSRFだとかヴァリデーターとかは今回はノータッチで

仕様は

な感じなのを作成したり削除したり更新したり等をやってみるのだけど、チェックポイントとして

  • 削除時にはエントリーとカテゴリーを結びつけな中間参照を保管しているentry_categoryテーブルからもデータを消す
  • 更新時に中間参照を再構築する

ビュー的な所はかかないけど

んな感じで

app/models/category.rb

class Category < ActiveRecord::Base
  has_and_belongs_to_many :entry, :join_table => "entry_category"
  has_many :sub_category, :class_name => "Category", :foreign_key => "parent"
  belongs_to :parent_category, :class_name => "Category", :foreign_key => "parent"

  def self.table_name
    "category"
  end
end

上記仕様な画像中には書かれて無いけど、Categoryにはparentっていうカラムでカテゴリー自体が参照する親カテゴリーなIDを持つ。それをhas_manyしてサブカテゴリーを参照できるように。例的に「Category.find(ID).sub_category」すると

[
  #<Category id: 5, name: "JavaScript", parent: 15, sort: 2>,
  #<Category id: 6, name: "Hadoop", parent: 15, sort: 5>,
  #<Category id: 11, name: "Google App Engine", parent: 15, sort: 4>,
  #<Category id: 14, name: "HTML", parent: 15, sort: 1>,
  #<Category id: 16, name: "HBase", parent: 15, sort: 6>,
  #<Category id: 19, name: "Algorithm", parent: 15, sort: 3>
]

な感じでカテゴリーが持つ子カテゴリーを参照できるようにと。sortはやつは今回は無視

で更にbelongs_toでもってカテゴリーが参照されている親カテゴリーを認識出来るように。こちらも例的に「Category.find(ID).parent_category」をすると(上記でID=5は親が15になっているので)

#<Category id: 15, name: "その他", parent: 0, sort: 8>

というように親カテゴリの参照が取れる。無ければnil

まぁ今回そこまったく使ってないのであくまで余談的なネタとして

app/models/entry.rb

class Entry < ActiveRecord::Base
  has_and_belongs_to_many :category, :join_table => "entry_category"
  default_scope :order => "created_at DESC"
  attr_accessible :title, :content, :category
  before_destroy :destroy_category_cleanup

  def self.table_name
    return "entry"
  end

  def category=(s)
    if s.is_a?(String)
      category.clear

      s.split(",").each do |c|
        category.push Category.where(:name => c).first_or_initialize
      end
    end
  end

  private
    def destroy_category_cleanup
      category.clear
    end
end

categoryに代入な辺りで文字列をカンマ区切りでスプリットして、それからCategoryな参照を取得する処理を突っ込む。で更新する際に再構築しないと重複する部分が出てきてしまうので、clearする事で中間参照なデータを消せる模様。それを利用して、削除する際にも中間参照なデータをclearで消すっていう感じかと

app/controllers/entry_controller.rb

class EntryController < ApplicationController

  def index
    @entries = Entry.all(:limit => 10)
  end

  def create
    entry = Entry.new(params[:entry])
    entry.save()

    redirect_to :action => :index
  end

  def edit
    @entry = Entry.find_by_id(params[:id])

    render :new
  end

  def update
    entry = Entry.find_by_id(params[:entry][:id])
    entry.title = params[:entry][:title]
    entry.content = params[:entry][:content]
    entry.category = params[:entry][:category]
    entry.save

    redirect_to :action => :index
  end

  def delete
    entry = Entry.find_by_id(params[:id])

    unless entry.nil?
      entry.destroy
    end

    redirect_to :action => :index
  end
end

特にあーだらこーだら書く必要ないかなと

RubyOnRails演習 (2) HABTM(はびたむ)