#189 Embedded Association
Nov 23, 2009 | 14 minutes | Active Record, Views
Learn how to set up a one-to-many or many-to-many association which is entirely embedded into a single column through a string or bitmask.
- Download:
- source codeProject Files in Zip (106 KB)
- mp4Full Size H.264 Video (18.2 MB)
- m4vSmaller H.264 Video (13.5 MB)
- webmFull Size VP8 Video (38.8 MB)
- ogvFull Size Theora Video (25.1 MB)
Resources
One to Many
bash
script/generate migration add_role_to_users role:string
rake db:migrate
script/generate migration add_role_to_users role:string rake db:migrate
models/user.rb
class User < ActiveRecord::Base
acts_as_authentic
has_many :articles
has_many :comments
ROLES = %w[admin moderator author]
def role_symbols
[role.to_sym]
end
end
class User < ActiveRecord::Base acts_as_authentic has_many :articles has_many :comments ROLES = %w[admin moderator author] def role_symbols [role.to_sym] end end
users/new.html.erb
<p>
<%= f.label :role %><br />
<%= f.collection_select :role, User::ROLES, :to_s, :titleize %>
</p>
<p> <%= f.label :role %><br /> <%= f.collection_select :role, User::ROLES, :to_s, :titleize %> </p>
Many to Many
bash
script/generate migration add_roles_mask_to_users roles_mask:integer
rake db:migrate
script/generate migration add_roles_mask_to_users roles_mask:integer rake db:migrate
models/user.rb
class User < ActiveRecord::Base
acts_as_authentic
has_many :articles
has_many :comments
named_scope :with_role, lambda { |role| {:conditions => "roles_mask & #{2**ROLES.index(role.to_s)} > 0"} }
ROLES = %w[admin moderator author]
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum
end
def roles
ROLES.reject { |r| ((roles_mask || 0) & 2**ROLES.index(r)).zero? }
end
def role_symbols
roles.map(&:to_sym)
end
end
class User < ActiveRecord::Base acts_as_authentic has_many :articles has_many :comments named_scope :with_role, lambda { |role| {:conditions => "roles_mask & #{2**ROLES.index(role.to_s)} > 0"} } ROLES = %w[admin moderator author] def roles=(roles) self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum end def roles ROLES.reject { |r| ((roles_mask || 0) & 2**ROLES.index(r)).zero? } end def role_symbols roles.map(&:to_sym) end end
users/new.html.erb
<p>
<%= f.label :roles %><br />
<% for role in User::ROLES %>
<%= check_box_tag "user[roles][]", role, @user.roles.include?(role) %>
<%=h role.humanize %><br />
<% end %>
<%= hidden_field_tag "user[roles][]", "" %>
</p>
<p> <%= f.label :roles %><br /> <% for role in User::ROLES %> <%= check_box_tag "user[roles][]", role, @user.roles.include?(role) %> <%=h role.humanize %><br /> <% end %> <%= hidden_field_tag "user[roles][]", "" %> </p>

