read

Mongoid document supports array field. Mongoid array field is a ruby array but it becomes quite complex to manage array field in rails forms.

I didn’t find anything matching on google as well on stackoverflow hence decided to dig into rails form helpers (form_for, fields_for).

Finally i am pleased to get it working as expected :)

In below example, product can have multiple categories :

<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>class Product </div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'> CATEGORIES = %w(Apparel Media Software Sports Agri Education) </div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'> include Mongoid::Document </div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'> field :name, :type => String </div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'> field :categories, :type => Array </div></div><div data-line='6' class='code-highlight-row numbered'><div class='code-highlight-line'>end</div></div></pre></div>

Here is form code

<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>= form_for(@product) do |f| </div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'> = f.text_field :name </div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'> - Product::CATEGORIES.each do |category| </div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'> = f.check_box :categories, :name => "product[categories][]", category</div></div></pre></div>

Here is products controller code

<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>class ProductsController < ApplicationController </div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'> before_filter :load_product, :only => [:new, :create] </div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'> [...] </div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='6' class='code-highlight-row numbered'><div class='code-highlight-line'> # We don't need new action to be defined </div></div><div data-line='7' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='8' class='code-highlight-row numbered'><div class='code-highlight-line'> def create </div></div><div data-line='9' class='code-highlight-row numbered'><div class='code-highlight-line'> @product.attributes = params[:product] </div></div><div data-line='10' class='code-highlight-row numbered'><div class='code-highlight-line'> # Here we need to reject blank categories </div></div><div data-line='11' class='code-highlight-row numbered'><div class='code-highlight-line'> @product.categories.reject!(&:blank?) </div></div><div data-line='12' class='code-highlight-row numbered'><div class='code-highlight-line'> if @product.save </div></div><div data-line='13' class='code-highlight-row numbered'><div class='code-highlight-line'> flash[:notice] = I18n.t('product.create.success') </div></div><div data-line='14' class='code-highlight-row numbered'><div class='code-highlight-line'> redirect_to(:action => :index) </div></div><div data-line='15' class='code-highlight-row numbered'><div class='code-highlight-line'> else </div></div><div data-line='16' class='code-highlight-row numbered'><div class='code-highlight-line'> render :action => :new </div></div><div data-line='17' class='code-highlight-row numbered'><div class='code-highlight-line'> end </div></div><div data-line='18' class='code-highlight-row numbered'><div class='code-highlight-line'> end </div></div><div data-line='19' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='20' class='code-highlight-row numbered'><div class='code-highlight-line'> [...] </div></div><div data-line='21' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='22' class='code-highlight-row numbered'><div class='code-highlight-line'> private </div></div><div data-line='23' class='code-highlight-row numbered'><div class='code-highlight-line'> def load_product </div></div><div data-line='24' class='code-highlight-row numbered'><div class='code-highlight-line'> @product = Product.new </div></div><div data-line='25' class='code-highlight-row numbered'><div class='code-highlight-line'> end </div></div><div data-line='26' class='code-highlight-row numbered'><div class='code-highlight-line'>end</div></div></pre></div>

Blog Logo

Sandip Ransing


Published

Image

Fun On Rails

Journal of a Web Developer #ruby #rails #JS

Back to Overview