acts_asを使ってみよう
DESCRIPTION
Rails勉強会@東北の資料ですTRANSCRIPT
![Page 1: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/1.jpg)
acts asを使ってみよう
藤岡岳之 (xibbar)
![Page 2: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/2.jpg)
アジェンダ
• acts as list
• acts as tree
• acts as nested set
• better nested set
![Page 3: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/3.jpg)
acts as listとは
• Railsに標準でついている
• 順列を扱うときに便利
![Page 4: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/4.jpg)
どうやって使う?• positionというinteger型のカラムを追加• modelにacts_as_listを追加
class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.column :name, :string t.column :position, :integer end end
def self.down drop_table :users endend
class User < ActiveRecord::Base acts_as_list validates_presence_of :nameend
![Page 5: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/5.jpg)
使えるメソッド
• decrement_position(ポジションを1減らす)• first?(最初かどうか)• higher_item(次のアイテムを返す)• in_list?(リストに入っているかどうか)• increment_position(ポジションを1増やす)• insert_at(ポジション指定して挿入)• last?(最後かどうか)• lower_item(前のアイテムを返す)• move_higher(次のポジションへ移動)• move_lower(前のポジションへ移動)• move_to_bottom(最後のポジションへ移動)• move_to_top(最初のポジションへ移動)• remove_from_list (リストから削除)
![Page 6: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/6.jpg)
position範囲を限定できる
• acts_as_listに:scope=>XXXを入れる
class CreateMobileSuits < ActiveRecord::Migration def self.up create_table :mobile_suits do |t| t.column :group_id,:integer t.column :position,:integer t.column :name, :string end end
def self.down drop_table :mobile_suits endend
class MobileSuit < ActiveRecord::Base belongs_to :group acts_as_list :scope => :groupend
![Page 7: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/7.jpg)
矛盾に注意
• XXcrement_position
• どういう時につかうのか???
• remove_from_list
• メソッドを実行した後にpositionにnilを入れないと矛盾する
![Page 8: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/8.jpg)
acts as treeとは?
• Railsに標準でついている
• モデルでツリー表現を支援
![Page 9: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/9.jpg)
どうやって使う?• parent_idというinteger型のカラムを追加• modelにacts_as_treeを追加
class CreateDepartments < ActiveRecord::Migration def self.up create_table :departments do |t| t.column :name, :string t.column :parent_id, :integer end end
def self.down drop_table :departments endend
class Department < ActiveRecord::Base acts_as_tree :order => :idend
![Page 10: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/10.jpg)
使えるメソッド• ancestors(一番上の親までの一覧を配列で返す)• root(一番上の親)• self_and_siblings(siblings+自分)• siblings(自分と同じ場所にある要素一覧)
実はbelongs_toでparent、has_manyでchildrenを定義している。この他にhas_manyとbelongs_toで定義したものを使える
department=Department.find(5)department.children.create(:name=>”開発部”)
department.root.name #福島支社
![Page 11: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/11.jpg)
acts as tree 寸感
• 仕組みがとてもシンプルでわかりやすい
• 自分の親を把握するのが楽
• 自分の直接の子は把握できるが、子の子以降を把握するのは面倒
• 例えば、自分の子が一発で配列で欲しいよね。現状では再帰で頑張るはめに。
![Page 12: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/12.jpg)
acts as nested setとは?
• Railsに標準でついている• モデルでツリー表現を支援• データの表現の仕方がacts as treeと異なる
![Page 13: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/13.jpg)
acts as nested setの表現 root |_ Child 1 |_ Child 1.1 |_ Child 1.2 |_ Child 2 |_ Child 2.1 |_ Child 2.2
このようなツリーがあった時、 ___________________________________________________________________ ¦ Root ¦ ¦ ____________________________ ____________________________ ¦ ¦ ¦ Child 1 ¦ ¦ Child 2 ¦ ¦ ¦ ¦ __________ _________ ¦ ¦ __________ _________ ¦ ¦ ¦ ¦ ¦ C 1.1 ¦ ¦ C 1.2 ¦ ¦ ¦ ¦ C 2.1 ¦ ¦ C 2.2 ¦ ¦ ¦ 1 2 3_________4 5________6 7 8 9_________10 11_______12 13 14 ¦ ¦___________________________¦ ¦___________________________¦ ¦ ¦___________________________________________________________________¦
ID ¦ PARENT ¦ LEFT ¦ RIGHT ¦ DATA 1 ¦ 0 ¦ 1 ¦ 14 ¦ root 2 ¦ 1 ¦ 2 ¦ 7 ¦ Child 1 3 ¦ 2 ¦ 3 ¦ 4 ¦ Child 1.1 4 ¦ 2 ¦ 5 ¦ 6 ¦ Child 1.2 5 ¦ 1 ¦ 8 ¦ 13 ¦ Child 2 6 ¦ 5 ¦ 9 ¦ 10 ¦ Child 2.1 7 ¦ 5 ¦ 11 ¦ 12 ¦ Child 2.2
何がいいって、leafの検索がselect一発!!反面、おそらく構造が崩れたらピンチ
![Page 14: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/14.jpg)
どうやって使う?• parent_id,lft,rgtというinteger型のカラムを追加• modelにacts_as_nested_setを追加
class CreateOrganizations < ActiveRecord::Migration def self.up create_table :organizations do |t| t.column :name, :string t.column :parent_id, :integer t.column :lft, :integer t.column :rgt, :integer end end
def self.down drop_table :organizations endend
class Organization < ActiveRecord::Base acts_as_nested_setend
![Page 15: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/15.jpg)
使えるメソッド• add_child(child)(子を追加)
• all_children(子すべて)
• before_destroy(ネストを外して削除できる状態にする)
• child?(子どもかどうか)
• children_count(子の数)
• direct_children(直接の子)
• full_set(子全部と自分自身)
• root?(一番上の親かどうか)
• unknown?(自分自身が意味不明かどうか)
![Page 16: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/16.jpg)
acts as nested set 寸感
• 別の枝にぶら下げるのはどうすんのよ。
• before_destroyしてadd_child(めんどくさ)
• 深さを調べるにはどうすんのよ。
• やっぱり微妙にメソッドが足りない
そこで。。。
![Page 17: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/17.jpg)
better nested set• http://d.hatena.ne.jp/xibbar/20060922#1159014466
• move_to_child_of 別の場所にぶら下げる• move_to_right_of別の場所にぶら下げる• move_to_left_of別の場所にぶら下げる• root 一番元の親• roots 一番トップの親を配列で返す• level 枝の深さ• ancestors 一番元の親から直接の親までの配列• self_and_ancestors 上+自分• siblings 自分と同じレベルの要素の配列• self_and_siblings 上+自分• children_count 子の数• children 直接の子の配列• all_children 子すべての配列(孫などを含む)• left_col_name 左の名前• right_col_name 右の名前• parent_col_name 親の名前
![Page 18: acts_asを使ってみよう](https://reader034.vdocuments.site/reader034/viewer/2022052216/54c8dbdc4a7959e2498b462b/html5/thumbnails/18.jpg)
おしまい
• まじめに作ってみました。
• おしまい。