My Brain is Open.

思いついたことを適当に列列と

参照のあるモデルをviewから作る

ParentとChildの関係にあるモデルの作り方と簡単な使いかたを前回書いたが、では画面からそれらを登録していくにはどうすればいいか。

考えられる方法はとりあえず二つ

  1. 作成済みのParentのページにChildを作るリンクを作成する
  2. Childを新規作成するページで既存のParentを指定できるようにする

モデルは仮に以下のようにしておく

class Parent
  include Mongoid::Document
  field :name, :type => String
  field :age, :type => Integer
  references_many :child
end

class Child
  include Mongoid::Document
  field :name, :type => String
  field :age, :type => Integer
  referenced_in :parent
end

1.についてはParentのObjectIDを引き渡せば良いと思われる。後は2.の途中からと同じ手順になるはず。
2.について、まずは(scaffoldで作った場合の)newをいじる。

Parentをプルダウンで選択するようにするには、selectを用いる。viewを全部書くと非常に面倒なので部分的に書くと、以下のような感じ。

form_for :child do |f|
  f.label :parent
  f.select :parent, Parent.all.map { |parent| [parent.name, parent.id] }
end

意味は params[:child][:parent]に関するセレクタを[name, id]の組み合わせの配列で作成する、ということになる。
ここで、配列 [ [n1,m1], [n2,m2] ] が渡されたときのselectは「表示"n1"に対してvalue="m1", 表示"n2"に対してvalue="m2"」となり、上記の例で実際にparams[:child][:parent]に渡される値はparent.id(つまり選んだParentのBSON::Objectid)となる。
このままだと、controller側のChild.newで:parentが余計に含まれてしまい失敗してしまうので、:parentを消しつつ、対応するParentを呼び出して参照関係を作る。

@parent = Parent.criteria.id(params[:child][:parent]).first
params[:child].delete(:parent)
@child = Child.new(params[:child])
@parent.child << @child

@child.save

諸々省略したが、これで参照を作る事ができる。