0

ENV:

Rails-3.2.12

Ruby-1.9.3

Mongoid-3.1.1

I have model:

class Item
   include Mongoid::Document
   field :name, type: String
   field :type, type: String
end

but if I try to add dynamic field in view, lets say "color", i get an undefined method error.

allow_dynamic_fields: true is enabled in the config file.

_form.html.erb:

<%= form_for(@item) do |f| %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
<div class="field">
  <%= f.label :type %><br />
  <%= f.text_field :type %>
</div>
<div class="field">
  <%= f.label :color %><br />
  <%= f.text_field :color %>
</div>

everything works fine if I try to edit item which already have color attribute. I need to add several dynamic attributes which depends on item.type but without something like this:

<% if @item[:color] %>
  <%= f.text_field :color %>
<%else%>
  <%= text_field_tag 'item[color]' %>
<% end %>

EDIT:

Error:

NoMethodError in Items#new

Showing /app/views/items/_form.html.erb where line #31 raised:

undefined method `color' for # Extracted source (around line #31):

28:     <%= f.number_field :type %>
29:   </div>
30:    <%= f.label :color %><br />
31:     <%= f.text_field :color %>
32:     <div class="actions">
33:       <%= f.submit %>
34:     </div>
xinu
  • 43
  • 1
  • 9

1 Answers1

0

Mongoid docs says:

"If the attribute does not already exist on the document, Mongoid will not provide you with the getters and setters and will enforce normal method_missing behavior. In this case you must use the other provided accessor methods: ([] and []=) or (read_attribute and write_attribute). "

The easiest thing you can do is to set 'color' in your controller #new method using write_attribute or []=

@item['color'] = ''

Or you can just dynamically add 'color' attribute to your new Item singleton class:

class << @item
  field :color, type: String
end
cthulhu
  • 3,749
  • 1
  • 21
  • 25
  • yes that works, but i will have like 30 attributes for item, isnt there an not ugly way to add attributes? otherwise i can just put them into model – xinu Feb 18 '13 at 16:02
  • It depends. If there is a constant set of attributes, you should just add them to your model. If you need to dynamically define Item attributes (e.g. change them in runtime) than you should IMO define them on the singleton class level. View layer doesn't seem to be an appropriate place to define them. – cthulhu Feb 18 '13 at 16:11
  • there is constant set of items, but every item will have different set of them, dependent on type – xinu Feb 18 '13 at 16:16
  • I think you should just put them into your model, but maybe you should consider creating Item subclasses, representng each 'type'. some other options: implement your Item#method_missing method and add attribute on the fly, or make form helpers use []/[]= instead of getters/setters – cthulhu Feb 18 '13 at 16:33