David Lelong пишет:
Hi,
I have two objects:
Contacts
Lists
I want to be able to add multiple contacts to multiple lists.
I've created a linking table and a form that allows me to select the contacts using checkboxes, but I'm having some problems with the controller and model.
I receive the following error message when I submit the form:
Mysql::Error: Cannot add or update a child row: a foreign key constraint fails: INSERT INTO contact_lists (`contact_id`, `list_id`) VALUES(1, 2)
However, the form variables returned from the form are:
Parameters: {"commit"=>"Add Contacts to List", "contact_list"=>{"contact_id"=>["4", "5"], "list_id"=>"2"}}
I'm not sure if the issue is with the way my controller is setup or the model.
The controller action is:
def link_contacts
@contact_list = Contact_List.new(params[:contact_list])
if @contact_list.save
flash[:notice] = 'Contacts were successfully added to the list.'
redirect_to :action => 'list'
else
flash[:notice] = 'Error with adding contacts to the list.'
end
end
Any advice?
You are trying to pass an array as an attribute value ("contact_id"). This won't work. You have to iterate through all items in params[:contact_list][:contact_id]:
@contacts = params[:contact_list][:contact_id].collect { |contact_id| Contact_List.new(:list_id => params[:list_id], :contact_id => contact_id) }
But I'm in doubt you have business model designed right.
@contacts = params[:contact_list][:contact_id].collect { |contact_id|
Contact_List.new(:list_id => params[:list_id], :contact_id =>
contact_id) }
Ahh.. don't ever copy/paste the code. Read it, get the idea and then type it
YOURSELF. Here is the corrected one:
@contacts = params[:contact_list][:contact_id].collect { |contact_id|
Contact_List.new(:list_id => params[:contact_list][:list_id], :contact_id =>
contact_id) }
By the way, you should create an abstraction for link between Contact and List
and name the corresponding class according to that abstraction. Contact_List
looks not very nice for me.
David Lelong wrote:
I'm still receiving an error message when I don't select a contact_id:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.collect
Any advice?
This is because you use checkboxes in the HTML and they do not produce
any post parameter if they aren't selected. My suggestion is to add
"rescue" clause for that case:
@contact_lists = .......... rescue
The middle part is unchanged, only add "rescue " to catch any errors
and return empty array then. Alternatively, you can wrap all construct
in an IF block:
if params[:contact_list] && params[:contact_list][:contact_id]
@contact_lists = ....................
end
Hello David,
Ugh, it had to do with:
validates_uniqueness_of :contact_id, :list_id
in my controller
Any advice on how I can get validate for uniqueness on the combination
of contact_id and list_id, not each one individually?
You were not so far
Use :scope.
validates_uniqueness_of :contact_id, :scope => :list_id
Regards,
-- Jean-François.