Hi, Thanks for taking a look at this. I am in need of some guidance for a particular problem: My Requirements: The concept of a user The concept of a badge A badge is simply a small image over the user''s avatar that displays extra information about the user. An admin user will be able to assign a badge to any user and the assigned badge will become the user''s current badge, displayed for all the world to see. Not required for now but required in the future: a user will be able to choose from a list of badges and create their own custom badges. The Way of the Lost: After toying with these requirements and bits of code for a few days, I have decided to ask for help. Please enlighten me on a better, a more rails way of implementing this. I am truly curious to know. There MUST be a better way! RELATIONSHIPS: I decided to implement the requirements by using a HasManyThrough association. I have three classes that collaborate: User, Badge, UserBadge class User < ActiveRecord::Base has_many :user_badges has_many :badges, :through => :user_badges has_one :current_badge, :class_name => "UserBadge", :conditions => { :current => true } end class Badge < ActiveRecord::Base # t.string :title # t.string :image_file_name # t.string :image_content_type # t.integer :image_file_size # t.datetime :image_updated_at # t.timestamps has_many :user_badges has_many :users, :through => :user_badges end class UserBadge < ActiveRecord::Base # t.integer :user_id # t.integer :badge_id # t.boolean :current, :default => false # t.timestamps belongs_to :user belongs_to :badge end ASSIGNING A CURRENT BADGE: I need a way to assign a badge to a user, so I created an attr_accessor in the User class called :assign_current_badge Then, I override the assign_current_badge setter method. The assign_current_badge=(badge_id) method: * accepts a badge_id as a formal parameter * updates any other current user_badges to "current=false" with the deactivate_badges method * checks for existance of a user_badge with the user''s id and badge_id * setting the user_badge.current to true if it exists * creating and setting the user_badge.current to true if it does not exist * sets the user''s current_badge_id to the badge_id class User < ActiveRecord::Base ... # relationships attr_accessor :assign_current_badge def assign_current_badge=(badge_id) deactivate_badges if UserBadge.exists?(:user_id => id, :badge_id => badge_id) user_badges.find_by_badge_id(badge_id).update_attribute(:current, true) else user_badges.create!(:badge => Badge.find(badge_id), :current => true) end self.current_badge_id = badge_id end def deactivate_badges user_badges.update_all("current = 0") end end PROBLEMS I HAVE ENCOUNTERED: The main problem I encounter is setting the current badge to a blank value through the user''s edit form. "Couldn''t find Badge with ID=" is being raised since there really is no badge with a blank id. This tells me, obviously, that there is a better way to go about this. My gut tells me there is something shady about passing in the badge_id instead of an existing badge object. - form_for @user, :url => admin_user_path(@user) do |f| = f.error_message # ... more fields %div = f.label :assign_current_badge = f.select :assign_current_badge, Badge.all.map {|b| [b.title, b.id]}, { :selected => @user.current_badge_id, :include_blank => true } # ... submit button Finale: If you have any advice for me, please reply. Hopefully I explained my situation well enough through code and writing. If you would like me to elaborate on anything, just ask. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Julian Leviston
2009-Feb-05 00:02 UTC
Re: We don''t need no stinking Badges! Guidance, anyone?
Could you explain your problem more clearly? The rest was beautiful. Blog: http://random8.zenunit.com/ Learn rails: http://sensei.zenunit.com/ On 05/02/2009, at 6:37 AM, Lake Denman <rails-mailing-list@andreas- s.net> wrote:> > Hi, Thanks for taking a look at this. I am in need of some guidance > for > a particular problem: > > My Requirements: > The concept of a user > The concept of a badge > > A badge is simply a small image over the user''s avatar that displays > extra information about the user. > An admin user will be able to assign a badge to any user and the > assigned badge will become the user''s current badge, displayed for all > the world to see. > > Not required for now but required in the future: a user will be able > to > choose from a list of badges and create their own custom badges. > > > The Way of the Lost: > > After toying with these requirements and bits of code for a few > days, I > have decided to ask for help. > Please enlighten me on a better, a more rails way of implementing > this. > I am truly curious to know. There MUST be a better way! > > > RELATIONSHIPS: > > I decided to implement the requirements by using a HasManyThrough > association. > I have three classes that collaborate: User, Badge, UserBadge > > class User < ActiveRecord::Base > has_many :user_badges > has_many :badges, :through => :user_badges > has_one :current_badge, :class_name => "UserBadge", :conditions => > { :current => true } > end > > class Badge < ActiveRecord::Base > # t.string :title > # t.string :image_file_name > # t.string :image_content_type > # t.integer :image_file_size > # t.datetime :image_updated_at > # t.timestamps > > has_many :user_badges > has_many :users, :through => :user_badges > end > > class UserBadge < ActiveRecord::Base > > # t.integer :user_id > # t.integer :badge_id > # t.boolean :current, :default => false > # t.timestamps > > belongs_to :user > belongs_to :badge > end > > ASSIGNING A CURRENT BADGE: > > I need a way to assign a badge to a user, so I created an > attr_accessor > in the User class called :assign_current_badge > Then, I override the assign_current_badge setter method. > > The assign_current_badge=(badge_id) method: > * accepts a badge_id as a formal parameter > * updates any other current user_badges to "current=false" with the > deactivate_badges method > * checks for existance of a user_badge with the user''s id and > badge_id > * setting the user_badge.current to true if it exists > * creating and setting the user_badge.current to true if it does > not > exist > * sets the user''s current_badge_id to the badge_id > > > class User < ActiveRecord::Base > ... # relationships > > attr_accessor :assign_current_badge > > def assign_current_badge=(badge_id) > deactivate_badges > if UserBadge.exists?(:user_id => id, :badge_id => badge_id) > user_badges.find_by_badge_id(badge_id).update_attribute(:current, > true) > else > user_badges.create!(:badge => Badge.find(badge_id), :current => > true) > end > self.current_badge_id = badge_id > end > > def deactivate_badges > user_badges.update_all("current = 0") > end > end > > PROBLEMS I HAVE ENCOUNTERED: > > The main problem I encounter is setting the current badge to a blank > value through the user''s edit form. > "Couldn''t find Badge with ID=" is being raised since there really is > no badge with a blank id. > This tells me, obviously, that there is a better way to go about > this. > My gut tells me there is something shady about passing in the badge_id > instead of an existing badge object. > > - form_for @user, :url => admin_user_path(@user) do |f| > = f.error_message > # ... more fields > %div > = f.label :assign_current_badge > = f.select :assign_current_badge, Badge.all.map {|b| [b.title, > b.id]}, { :selected => @user.current_badge_id, :include_blank => > true } > # ... submit button > > Finale: > If you have any advice for me, please reply. Hopefully I explained my > situation well enough through code and writing. If you would like me > to > elaborate on anything, just ask. > -- > Posted via http://www.ruby-forum.com/. > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Why do you even need a UserBadge model? I would have User model, a Badge model, where the relationship is User belongs_to :badge, and badge has_many :users. Then you can simply assign it with some_user.badge = some_badge. It seems like you''re adding complexity with the UserBadge model and the current attribute. Maybe I''m missing something but looks like, from the requirements you''ve outlined, you can drop that model altogether, and keep your design simple... -H On Feb 4, 2:37 pm, Lake Denman <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Hi, Thanks for taking a look at this. I am in need of some guidance for > a particular problem: > > My Requirements: > The concept of a user > The concept of a badge > > A badge is simply a small image over the user''s avatar that displays > extra information about the user. > An admin user will be able to assign a badge to any user and the > assigned badge will become the user''s current badge, displayed for all > the world to see. > > Not required for now but required in the future: a user will be able to > choose from a list of badges and create their own custom badges. > > The Way of the Lost: > > After toying with these requirements and bits of code for a few days, I > have decided to ask for help. > Please enlighten me on a better, a more rails way of implementing this. > I am truly curious to know. There MUST be a better way! > > RELATIONSHIPS: > > I decided to implement the requirements by using a HasManyThrough > association. > I have three classes that collaborate: User, Badge, UserBadge > > class User < ActiveRecord::Base > has_many :user_badges > has_many :badges, :through => :user_badges > has_one :current_badge, :class_name => "UserBadge", :conditions => > { :current => true } > end > > class Badge < ActiveRecord::Base > # t.string :title > # t.string :image_file_name > # t.string :image_content_type > # t.integer :image_file_size > # t.datetime :image_updated_at > # t.timestamps > > has_many :user_badges > has_many :users, :through => :user_badges > end > > class UserBadge < ActiveRecord::Base > > # t.integer :user_id > # t.integer :badge_id > # t.boolean :current, :default => false > # t.timestamps > > belongs_to :user > belongs_to :badge > end > > ASSIGNING A CURRENT BADGE: > > I need a way to assign a badge to a user, so I created an attr_accessor > in the User class called :assign_current_badge > Then, I override the assign_current_badge setter method. > > The assign_current_badge=(badge_id) method: > * accepts a badge_id as a formal parameter > * updates any other current user_badges to "current=false" with the > deactivate_badges method > * checks for existance of a user_badge with the user''s id and badge_id > * setting the user_badge.current to true if it exists > * creating and setting the user_badge.current to true if it does not > exist > * sets the user''s current_badge_id to the badge_id > > class User < ActiveRecord::Base > ... # relationships > > attr_accessor :assign_current_badge > > def assign_current_badge=(badge_id) > deactivate_badges > if UserBadge.exists?(:user_id => id, :badge_id => badge_id) > user_badges.find_by_badge_id(badge_id).update_attribute(:current, > true) > else > user_badges.create!(:badge => Badge.find(badge_id), :current => > true) > end > self.current_badge_id = badge_id > end > > def deactivate_badges > user_badges.update_all("current = 0") > end > end > > PROBLEMS I HAVE ENCOUNTERED: > > The main problem I encounter is setting the current badge to a blank > value through the user''s edit form. > "Couldn''t find Badge with ID=" is being raised since there really is > no badge with a blank id. > This tells me, obviously, that there is a better way to go about this. > My gut tells me there is something shady about passing in the badge_id > instead of an existing badge object. > > - form_for @user, :url => admin_user_path(@user) do |f| > = f.error_message > # ... more fields > %div > = f.label :assign_current_badge > = f.select :assign_current_badge, Badge.all.map {|b| [b.title, > b.id]}, { :selected => @user.current_badge_id, :include_blank => true } > # ... submit button > > Finale: > If you have any advice for me, please reply. Hopefully I explained my > situation well enough through code and writing. If you would like me to > elaborate on anything, just ask. > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---