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@googlegroups.com
To unsubscribe from this group, send email to 
rubyonrails-talk+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to