Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I wouldn't suggest a has_one relationship in this case. A User could <code>belongs_to :eye_color</code>, so you can map eyecolors across your users. An EyeColor <code>has_many :users</code>, so that you can do <code>@eye_color.users</code> and get all users with a specific EyeColor. Otherwise you will have to create an EyeColor for every user (or at least the ones with eyes).</p> <p>The reason I'd suggest this over your PersonProperty solution is because it's easier to maintain and because of the performance gain of delegating these kinds of relations to your database.</p> <p><strong>UPDATE:</strong> If dynamic attributes are what you want, I'd suggest to setup your models like this:</p> <pre><code>class Person &lt; ActiveRecord::Base has_many :person_attributes attr_accessible :gender accepts_nested_attributes_for :person_attributes end class PersonAttribute &lt; ActiveRecord::Base belongs_to :person_attribute_type belongs_to :person_attribute_value belongs_to :person attr_accessible :person_id, :person_attribute_value_id end class PersonAttributeValue &lt; ActiveRecord::Base has_many :person_attributes belongs_to :person_attribute_type attr_accessible :value, :person_attribute_type_id end class PersonAttributeType &lt; ActiveRecord::Base has_many :person_attribute_values attr_accessible :name, :type end </code></pre> <p>This way you can do the following:</p> <pre><code>@person_attribute_type = PersonAttributeType.create(:name =&gt; 'Eye color', :type =&gt; 'string') ['green', 'blue', 'brown'].each do |color| @person_attribute_type.person_attribute.values.build(:value =&gt; color) end @person_attribute_type.save @person = Person.new @person_attribute = @person.person_attributes.build @person_attribute.person_attribute_value = @person_attribute_type.person_attribute_values.find(:value =&gt; 'green') </code></pre> <p>Of course, you probably won't fill your database through the command line. You will probably be very curious as to how this would work in a form:</p> <pre><code>class PersonController # ... def new @person = Person.new PersonAttributeType.all.each do |type| @person.person_attributes.build(:person_attribute_type = type) end end def create @person = Person.new(params[:person]) if @person.save # ... else # ... end end def edit @person = Person.find(params[:id]) PersonAttributeType.where('id NOT IN (?)', @person.person_attributes.map(&amp;:person_attribute_type_id)).each do |type| @person.person_attributes.build(:person_attribute_type = type) end end # ... </code></pre> <p><em>Now the form, based on Formtastic:</em></p> <pre><code>semantic_form_for @person do |f| f.input :gender, :as =&gt; :select, :collection =&gt; ['Male', 'Female'] f.semantic_fields_for :person_attributes do |paf| f.input :person_attribute_value, :as =&gt; :select, :collection =&gt; paf.object.person_attribute_type.person_attributes_values, :label =&gt; paf.object.person_attribute_type.name end f.buttons end </code></pre> <p>Mind that this all is untested, so just try to understand what I'm trying to do here.</p> <p><em>BTW, I now realize that the class name Person</em><strong>Attribute</strong> <em>is probably a bit unlucky, because you will have to <code>accepts_nested_attributes_for :person_attributes</code> which would mean you would have to <code>attr_accessible :person_attributes_attributes</code>, but you get my drift I hope.</em></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload