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_开发者_JAVA技巧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.
精彩评论