Mam dziwny problem podczas zapisywania danych.
Posiadam model articles oraz model people. Oba połączone są relacją wiele-do-wielu. W modelu articles mam dodane accepts_nested_attributes_for :people. Tworzę formularz dodawania nowego artykułu. Tam mam dwa pola ukryte, które przechowują albo id wybranego autora albo jego nazwę, gdyby nie było i należało go utworzyć. Przy obsłudze formularza tworzę obiekty klasy person z odpowiednimi danymi. Następnie zapisuję artykuł. Wszystko odbywa się poprawnie z tą różnicą, że w tabeli złączeniowej przypisanie osoby do artykułu zapisuje mi się podwójnie. Tak się dzieje także z innymi powiązanymi modelami.
Ruby 1.8.7, rails 2.3.5 (niestety nie mogę przejść na 3)
Kod wygląda tak:
MODELE
[code]class Article < ActiveRecord::Base
has_many :contents
has_and_belongs_to_many :people
has_many :issues, :through => :contents
has_many :categories, :through => :contents
has_and_belongs_to_many :keywords
accepts_nested_attributes_for :contents
accepts_nested_attributes_for :people
accepts_nested_attributes_for :keywords[/code]
[code]class Person < ActiveRecord::Base
has_and_belongs_to_many :articles
validates_presence_of :surname[/code]
[code]class Keyword < ActiveRecord::Base
has_and_belongs_to_many :articles[/code]
KONTROLER
[code] #handle keywords
keywords = params[:article][:keywords].split(’, ')
params[:article][:keywords] = Array.new
keywords.each_with_index do |word, i|
params[:article][:keywords][i] = Keyword.retrieveKeyword(word)
end
#handle existing authors
if (params[:author_ids] != ‘’)
existing_authors = params[:author_ids].strip.split(’,’)
params[:article][:people] = Array.new
existing_authors.each_with_index do |id, i|
params[:article][:people][i] = Person.find(id)
end
end
#handle new authors
if (params[:new_authors] != '')
new_authors = params[:new_authors].strip.split(',')
if (params[:author_ids] == '')
params[:article][:people] = Array.new
end
new_authors.each do |author|
data = author.strip.split(' ')
if data.size > 1
params[:article][:people][i] = Person.new(:name => data[0].strip, :surname => data[1].strip)
else
params[:article][:people][i] = Person.new(:surname => data[1].strip)
end
end
end[/code]
Generalnie pole keywords zawiera ciąg tagów oddzielonych przecinkiem, podobnie pola z istniejącymi i nowymi autorami. Przetwarzam to by utworzyć odpowiedni obiekt i dodaje do tablicy obiektów. Na zakończenie pola
params[:article][:keywords] zawiera tablicę obiektów klasy Keyword, a params[:article][:people] tablicę obiektów klasy Person. W tym momencie podczas dodawania i autorzy i tagi zapisują się dwa razy
log
Processing ArticlesController#create (for 127.0.0.1 at 2011-05-11 01:51:34) [POST]
Parameters: {"article"=>{"title"=>"Test", "abstract"=>"test", "subtitle"=>"", "contents_attributes"=>{"0"=>{"category"=>"Testowa", "issue_id"=>"2", "page"=>"23", "item"=>"5"}}, "keywords"=>"test, "}, "commit"=>"Create", "new_authors"=>"", "authenticity_token"=>"EpfGG3/0mck+cAXsIsubz8WTeMNthvy1aYYvzSIYTr4=", "authors"=>"", "author_ids"=>"3"}
Issue Columns (0.7ms) SHOW FIELDS FROM `issues`
Issue Load (0.2ms) SELECT * FROM `issues`
Magazine Columns (0.6ms) SHOW FIELDS FROM `magazines`
Magazine Load (0.2ms) SELECT * FROM `magazines` WHERE (`magazines`.`id` = 1)
Magazine Load (0.2ms) SELECT * FROM `magazines` WHERE (`magazines`.`id` = 2)
Category Load (0.2ms) SELECT * FROM `categories` WHERE (name = 'Testowa')
Keyword Load (0.2ms) SELECT * FROM `keywords` WHERE (word = 'test')
Person Columns (0.5ms) SHOW FIELDS FROM `people`
Person Load (0.2ms) SELECT * FROM `people` WHERE (`people`.`id` = 3)
Article Columns (0.5ms) SHOW FIELDS FROM `articles`
SQL (0.1ms) BEGIN
SQL (0.1ms) COMMIT
Content Columns (0.5ms) SHOW FIELDS FROM `contents`
Category Columns (0.3ms) SHOW FIELDS FROM `categories`
SQL (0.0ms) BEGIN
Keyword Columns (0.3ms) SHOW FIELDS FROM `keywords`
SQL (0.0ms) COMMIT
SQL (0.0ms) BEGIN
Article Create (0.2ms) INSERT INTO `articles` (`created_at`, `title`, `updated_at`, `subtitle`, `abstract`) VALUES('2011-05-10 23:51:34', 'Test', '2011-05-10 23:51:34', '', 'test')
Content Create (0.1ms) INSERT INTO `contents` (`created_at`, `issue_id`, `updated_at`, `article_id`, `category_id`, `page`, `item`) VALUES('2011-05-10 23:51:34', 2, '2011-05-10 23:51:34', 17, 7, 23, 5)
SQL (0.5ms) describe `articles_people`
articles_people Columns (0.4ms) SHOW FIELDS FROM `articles_people`
SQL (0.2ms) INSERT INTO `articles_people` (`created_at`, `updated_at`, `article_id`, `person_id`) VALUES ('2011-05-09 22:14:55', '2011-05-10 20:42:18', 17, 3)
SQL (0.4ms) describe `articles_keywords`
articles_keywords Columns (0.3ms) SHOW FIELDS FROM `articles_keywords`
SQL (0.1ms) INSERT INTO `articles_keywords` (`created_at`, `updated_at`, `article_id`, `keyword_id`) VALUES ('2011-05-10 20:26:54', '2011-05-10 20:26:54', 17, 1)
SQL (0.4ms) describe `articles_people`
SQL (0.1ms) INSERT INTO `articles_people` (`created_at`, `updated_at`, `article_id`, `person_id`) VALUES ('2011-05-09 22:14:55', '2011-05-10 20:42:18', 17, 3)
SQL (0.3ms) describe `articles_keywords`
SQL (0.1ms) INSERT INTO `articles_keywords` (`created_at`, `updated_at`, `article_id`, `keyword_id`) VALUES ('2011-05-10 20:26:54', '2011-05-10 20:26:54', 17, 1)
SQL (8.4ms) COMMIT
Redirected to http://localhost:3000/articles/17
Completed in 65ms (DB: 16) | 302 Found [http://localhost/articles]
Czy te pola może powinny być inaczej sformatowane?