RubyOnRails演習 (1)
色々演習的な事やってみようかと、とりあえず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
特にあーだらこーだら書く必要ないかなと