views:

87

answers:

2

Hello,

I have 2 equal-access models: Users and Categories

Each of these should have the standard-actions: index, new, create, edit, update and destroy

But where do I integrate the associations, when I want to create an association between this two models?

Do I have to write 2 times nearly the same code:

class UsersController << ApplicationController

  # blabla
  def addCategory
    User.find(params[:id]).categories << Category.find(params[:user_id])
  end
end

class CategoriessController << ApplicationController
  # blabla
  def addUser
    Category.find(params[:id]).users << User.find(params[:user_id])
  end
end

Or should I create a new Controller, named UsersCategoriesController?

Whats the best practice here? The above example doens't look very DRY.... And a new controller is a little bit too much, I think?

Thanks!

EDIT:

I need to have both of these associations-adding-functions, because f.e.

#on the 
show_category_path(1)
# I want to see all assigned users (with possibility to assign new users)

and

#on the 
show_user_path(1)
#I want to see all assigned categories (with possibility to assign new categories)

EDIT:

I'm taking about a HBTM relationship.

A: 

You didn't mention if you are using has_and_belongs_to_many or if you are using has_many :through. I recommend has_many :through, which forces you to use an actual model for the join, something like UserCategory or Categorization something like that. Then you just make a new controller to handle creation of that.

You will want to pass the user and category as parameters to the create action of this controller.

Your form... <% form_tag categorizations_path(:category_id => @category.id), :method => :post do %> <%=text_field_tag "user_id" %> <%=submit_tag "Add user" %> <% end %>

Your controller...

class CategorizationsController < ApplicationController
   def create
     if Categorization.add_user_to_category(params[:user_id], params[:category_id])
        ...

   end
end

then your categorization class...

class Categorization
   belongs_to :user
   belongs_to :category

   def self.add_user_to_category(user_id, category_id)
     # might want to validate that this user and category exist somehow
     Categorization.new(:user_id => user_id, :category_id => category_id)
     Categorization.save
   end
end

The problem comes in when you want to send the users back, but that's not terribly hard - detect where they came from and send them back there. Or put the return page into a hidden field on your form.

Hope that helps.

Brian Hogan
Sorry, I'm taking about a HBTM relationship.
Lichtamberg
I'd recommend not doing that if at all possible. However I'll post an answer for habtm which is what I've used.
Brian Hogan
A: 

If you have a situation where you need to do this with has_and_belongs_to_many, you could take the approach you are currently using, or you could build this into your existing update actions.

When you add a habtm relationship, you will get an additional method on your classes...

class User < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

With this, you can do this:

user = User.find(params[:id])
user.category_ids = [1,3,4,7,10]
user.save

The categories with those ids will be set. If you name your form fields appropriately, the update can take care of this for you if you want to use checkboxes or multiselect controls.

If you need to add them one at a time, then the methods you've built in your original post are reasonable enough. If you think the repetition you have is a code smell, you are correct - this is why you should use the approach I outlined in my previous answer - an additional model and an additional controller.

Brian Hogan
Ok, saw there will be/is support for nested attributes.... I think that also helps... Thanks..
Lichtamberg