Rails + MongoMapper + EmbeddedDocument form help
Asked Answered
F

2

9

I am working on a pretty simple web application (famous last words) and am working with Rails 2.3.5 + MongoMapper 0.7.2 and using embedded documents. I have two questions to ask:

First, are there any example applications out there using Rails + MongoMapper + EmbeddedDocument? Preferably on GitHub or some other similar site so that I can take a look at the source and see where I am supposed to head? If not ...

... what is the best way to approach this task? How would I go about creating a form to handle an embedded document.

What I am attempting to do is add addresses to users. I can toss up the two models in question if you would like.

Thanks for the help!

Fingernail answered 26/3, 2010 at 19:11 Comment(0)
I
10

Here's the basic approach I took in one of my apps. Problem has many answers - problem is a document, answer is an embedded document. You can use the "add answer" link to generate another answer field, and the "remove" link to delete one.

_form.html.erb:

<% form_for @problem do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :content %><br />
    <%= f.text_area :content, :size => '50x7' %>
  </p>

  ...etc...

  <%= add_answer_link "(add answer)" %>
  <div id="answers">
    <%= render :partial => 'answer', :collection => @problem.answers %>
  </div>

  <p><%= f.submit "Submit" %></p>
<% end %>

_answer.html.erb:

<div class="answer">
  <% fields_for 'problem[answers]', answer, :index => nil do |f| -%>
    <%= f.label :content, "Answer #{answer.id}:" %>
    <%= f.text_field :content, :size => 50 %>
    <%= link_to_function "(remove)", "$(this).up('.answer').remove()" %>
  <% end -%>
</div>

problems_helper.rb

module ProblemsHelper
  def add_answer_link(name)
    link_to_function name do |page|
      page.insert_html :bottom, "answers", :partial => 'answer', :object => Answer.new
    end
  end
end

I cut out a couple minor bits of the implementation, but that should work.

Ichinomiya answered 26/3, 2010 at 20:0 Comment(5)
Thanks for the help, that give me some ideas. I'm wondering what your controller might look like. Does MongoMapper handle all of the mapping to did you do something else? Thanks!Fingernail
Nope - typical scaffolded controller, no special code in the models, and vanilla MongoMapper 0.7.0.Ichinomiya
Just a note. This code example doesn't seem to work if the "answer" has more than just one attribute.Megaron
Works just fine for me with more than one attribute. Granted, I haven't tried the AJAX-y part yet, but the basic form works great.Heartrending
index: nil doesn't work for me....instead i had to define a separate method as i.e 'answers_attributes=(attrs)'. to make it properly work on server side. reference #5817939Astoria
M
1

Even easier now -- update for Rails 4.1.1, ruby 2.1.1p76:

Models:

class Location
 include MongoMapper::EmbeddedDocument
  key :state, String, :default => "CA"
  key :zip, String
  timestamps!
end

class House
 include MongoMapper::Document
 timestamps!
 one :location
end

Controller:

def new
    @house = House.new
end

new.html.erb:

<%= form_for @house, url: houses_path do |house_form| %>
<p>
    <%= house_form.label :name %><br>
    <%= house_form.text_field :name %>
</p>

<%= house_form.fields_for :location do |address_fields| %>

    Street  : <%= address_fields.text_field :street %>
    Zip code: <%= address_fields.text_field :zip %>
<% end %>

<p>
    <%= house_form.submit %>
</p>
Menjivar answered 25/5, 2014 at 9:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.