1

I am using Ruby on Rails 3.0.7 and I have a problem on an associated model validation for an updating controller action. I am using an "has_many :through" association so that I can handle user-category relationships.

In the User model I have:

has_many :user_category_relationships,
  :autosave    => true,
  :dependent   => :destroy
has_many :user_categories,
  :through     => :user_category_relationships,
  :source      => :user_category,
  :dependent   => :destroy

In the _form view file I have:

<% @current_user.user_categories.each do |user_category| %>
  <%= check_box_tag :user_category_ids, user_category.id, @user.user_categories.include?(user_category), :name => 'user_relationships[user_category_ids][]' %>
  <%= label_tag "user_category_#{user_category.id}", user_category.name %>
<% end %>

In the UserCategoryRelationship model I have:

belongs_to :users
belongs_to :categories

# Validation
validates :name_id,
  :presence   => true,
  :uniqueness => {
    :scope          => [:created_by_user_id, :category_id]
  }
validates :category_id,
  :presence   => true,
  :uniqueness => {
    :scope          => [:created_by_user_id, :name_id]
  }
validates :created_by_user_id,
  :presence   => true,
  :uniqueness => {
    :scope          => [:category_id, :name_id]
  }

In the UsersController I have:

def create
  ...

  # `params[:user_relationships][:user_category_ids]` used below are id values 
  # related to user-category relationships.

  unless params[:user_relationships][:user_category_ids]
    # Set default user category if not selected.
    @user.user_category_relationships.build(
      :category_id        => '1',
      :created_by_user_id => @current_user.id,
      :name_id            => @name.id
    )
  else
    params[:user_relationships][:user_category_ids].each { |user_category_id|
      @user.user_category_relationships.build(
        :category_id        => user_category_id,
        :created_by_user_id => @current_user.id,
        :name_id            => @name.id
      )
    }
  end

  if @user.save
    ...
  end
end

def update
  ...

  # Note: The following code is equal to that in the controller 'create' 
  # action. However here is my problem because validation (read after 
  # for more information about).

  unless params[:user_relationships][:user_category_ids]
    # Set default user category if not selected.
    @user.user_category_relationships.build(
      :category_id        => '1',
      :created_by_user_id => @current_user.id,
      :name_id            => @name.id
    )
  else
    params[:user_relationships][:user_category_ids].each { |user_category_id|
      @user.user_category_relationships.build(
        :category_id        => user_category_id,
        :created_by_user_id => @current_user.id,
        :name_id            => @name.id
      )
    }
  end

  if @user.update_attributes(params[:user])
    ...
  end
end

The above code works except for the update action: when I try to run that I get always the same error, as well.

# Validation errors on updating the 'user_category_relationships' associated model
:"user_category_relationships.category_id"        =>["has already been taken"]
:"user_category_relationships.name_id"            =>["has already been taken"]
:"user_category_relationships.created_by_user_id" =>["has already been taken"]

What I would like to do, since I am not using the "RoR magical\automatic way" at all (that is, I don't use the collection_singular_ids method - see also this and this), is to make properly work the update controller action so that I can still use the "automatic" creation of user-category relationships (triggered on save and update_attributes(...) methods) but avoiding to generate above validation errors (that is, create valid data in the database table). How can I do? What do you advice about this issue?

P.S.: Where I am in trouble is in the update action, precisely figuring out how to "choose"\"filter" and "coding" records to update, to create and to delete in the database having params[:user_relationships][:user_category_ids] as input data.

Community
  • 1
  • 1
Backo
  • 18,291
  • 27
  • 103
  • 170
  • Can you put the code of your form view? – Dinatih Jul 05 '11 at 21:09
  • 1
    Can you put the code of your form view? the code of the post for handle has_and_belongs_to_many style assoc is very old! you can check this for start with magic http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for. I'm waiting for you view form before tell you more on the way to handle this – Dinatih Jul 05 '11 at 21:16
  • @Dinatih - I updated the question including the view file code. However my problem is that RoR doesn't "understand" to update records for which `category_id`, `name_id` and `created_by_user_id` are the same (that is, there are records with those attributes already stored in the database). Instead it of tries to create a new record. – Backo Jul 06 '11 at 05:15
  • @Dinatih - I would like to use check box input fields in a view file so to update user group relationships in the database. Relationships should be: *created* if check box input fields are selected and those relationships don't exist in the database; *deleted* if check boxes are not selected and those relationships exist in the database; *untouched* if check box input fields are selected and those relationships exist in the database. I would like to accomplish just that in a "good" and performant way. – Backo Jul 06 '11 at 07:10
  • ok, another things: what is the class of user_categories object ? If they are Category objects why do you not name @user.user_categories juste user @user.categories ? And you talk about UsersController or UserCategoryRelationshipsController, do you want to edit a User and assign it a list of categories (if so, why do you use @current_user) or edit the UserCategoryRelationship and assign it users and categories ? (the form view is from User or UserCategoryRelationship) – Dinatih Jul 06 '11 at 20:27
  • @Dinatih - You say: "another thing"... they are a lot! – Backo Jul 06 '11 at 21:38
  • :) it's for well understand your model. So ? – Dinatih Jul 06 '11 at 22:05
  • @Dinatih - I changed the development strategy... Thanks anyway. – Backo Jul 06 '11 at 22:17
  • Ok,so can you close this question, plz – Dinatih Jul 07 '11 at 16:02

0 Answers0