views:

45

answers:

1

I'm using Rails 3 and have a rich association between Projects and Users. The join model (UsersProject) has an additional boolean attribute, administrator, which flags the User as an admin of Project:

Sure I'm missing something obvious here, but is there a clean way to set the administrator attribute on the join model (UsersProject) when creating a new Project? e.g:

class Project < ActiveRecord::Base
  has_many :users_projects
  has_many :users, :through => :users_projects
end

class User < ActiveRecord::Base
  has_many :users_projects
  has_many :projects, :through => :users_projects

  # Guessing I use something along these lines, although should I be using scope?
  # has_many :administered_projects,
  #          :through => :users_projects,
  #          :source => :project,
  #          :conditions => ['users_projects.administrator = ?', true]
  #          ...
end

class UsersProject < ActiveRecord::Base
  # Join model has an boolean attribute :administrator
  belongs_to :user
  belongs_to :project
end

# INTENDED USAGE:

@project = @user.administered_projects.new(params[:project])
# => Creates a UsersProject record with `:administrator=true`

@project = @user.projects.new(params[:project])
# => Creates a UsersProject record with `:administrator=false`

Appreciate any help, Chris

+1  A: 

While not directly answering your question, the implementation seems a bit clunky to me.

If you had users and projects, the answer would be simple--you could just create a has_and_belongs_to_many relationship between the two models, and create a join table. The administrator flag makes the situation slightly more tricky, but I'm not sure having a join model would be necessary.

Personally, I'd simply set up two relationships between the models, like this:

class Project < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_and_belongs_to_many :administrators, :class_name => 'User', :join_table => 'administrators_projects' # potentially some foreign_key directives here as well
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :projects
  has_and_belongs_to_many :administered_projects, :class_name => 'Project', :join_table => 'administrators_projects' # potentially some foreign_key directives here as well
end

This way, you'll still only have your two models, but with all the functionality you'd need (and your "INTENDED USAGE" structures would work). If you wanted to, you could add the administrators to the projects_users relationship as well (so that admins are both admins and users), but that would be completely up to how you want to structure the rest of the table.

(As a minor sidenote; you may get more answers in the future if you accept answers to previous questions. Many users on StackOverflow are more reluctant to answer question when they see the requester's accept rate being as low as yours.)

vonconrad
Thanks for your answer, and a much cleaner way of doing what I need to do. Appreciate your help to - I hadn't noticed the accept rate before.
Chris