Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested fields with mongodb

I'm trying to create nested fields using mongodb. For that I'm using the gem mongomodel which allows work with ruby and mongodb and I'm using the gem nested_form, to create dynamics nested fields. I'm having the following trouble:

undefined methodreflect_on_association' for #`

Other errors like it, that I have found in the internet doesn't really match what I want to do here with mongodb. I'm new to RoR, and I don't know how to solve this. Can anyone help me?

Here is my models:

survey.rb

class Survey < MongoModel::Document
  property :name, String
  property :questions, Collection[Question]
  timestamps!

  accepts_nested_attributes_for :questions, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

questions.rb

class Question < MongoModel::Document
  property :content, String
  timestamps!
end

My controller:

surveys_controller.rb
class SurveysController < ApplicationController
  # GET /surveys
  # GET /surveys.json
  def index
    @surveys = Survey.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @surveys }
    end
  end

  # GET /surveys/1
  # GET /surveys/1.json
  def show
    @survey = Survey.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @survey }
    end
  end

  # GET /surveys/new
  # GET /surveys/new.json
  def new
    @survey = Survey.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @survey }
    end
  end

  # GET /surveys/1/edit
  def edit
    @survey = Survey.find(params[:id])
  end

  # POST /surveys
  # POST /surveys.json
  def create
    @survey = Survey.new(params[:survey])

    respond_to do |format|
      if @survey.save
        format.html { redirect_to @survey, notice: 'Survey was successfully created.' }
        format.json { render json: @survey, status: :created, location: @survey }
      else
        format.html { render action: "new" }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /surveys/1
  # PUT /surveys/1.json
  def update
    @survey = Survey.find(params[:id])

    respond_to do |format|
      if @survey.update_attributes(params[:survey])
        format.html { redirect_to @survey, notice: 'Survey was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /surveys/1
  # DELETE /surveys/1.json
  def destroy
    @survey = Survey.find(params[:id])
    @survey.destroy

    respond_to do |format|
      format.html { redirect_to surveys_url }
      format.json { head :no_content }
    end
  end
end

My gemfile:

source 'https://rubygems.org'

gem 'rails', '3.2.8'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem "mongomodel"
gem "bson_ext"
gem "nested_form"

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem 'therubyracer', :platforms => :ruby

  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# To use Jbuilder templates for JSON
# gem 'jbuilder'

# Use unicorn as the app server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'debugger'

My view of survey:

_form.html.erb
<%= nested_form_for(@survey) do |f| %>
  <% if @survey.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@survey.errors.count, "error") %> prohibited this survey from being saved:</h2>

      <ul>
      <% @survey.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <p>
    <%= f.fields_for :questions do |builder| %>
    <p>
        <%= builder.label :content, "Question" %>
    <%= builder.text_area :content, :rows => 3 %>
    </p>    
    <% end %>
    <p><%= f.link_to_add "Add a Question", :questions %></p>
  </p>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
like image 539
lucianthomaz Avatar asked Nov 01 '12 17:11

lucianthomaz


People also ask

How do you match a nested field in MongoDB?

Match an Embedded/Nested Document To specify an equality condition on a field that is an embedded/nested document, use the query filter document { <field>: <value> } where <value> is the document to match.

Can we create nested collection in MongoDB?

In MongoDB, you can only nest document up to 100 levels. The overall document size must not exceed 16 MB.

How do I query an inner document in MongoDB?

To specify a query condition on fields in an embedded/nested document, use dot notation ( "field. nestedField" ). When querying using dot notation, the field and nested field must be inside quotation marks.


1 Answers

I was trying to follow this railscast, but I wanted to work with mongodb, and I was using the gem mongomodel to do that. I wasn't able to do what I wanted because I got the error described above, and even for the button "Remove" I got another error that I can't remember now. Whatever, I really couldn't do what I wanted using mongomodel, so I tried to do that using mongoid and everything was easier.

like image 139
lucianthomaz Avatar answered Oct 24 '22 00:10

lucianthomaz