I have isolated a problem with rails3 and many 2 many associations in this sample rails3 app: git://github.com/mbj/bugapp
It is NOT reproducible under a non rails3 cache_classes = false environment.
The app is featuring two models:
class Article
include DataMapper::Resource
property :id, Serial
has n, :persons, :through => Resource
end
class Person
include DataMapper::Resource
property :id, Serial
has n, :articles, :through => Resource
end
One Controller:
class ApplicationController < ActionController::Base
protect_from_forgery
# routed from GET /a, creates some records needed for demonstration
# you have to hit it to get this demo working
def create_person_and_articles
person = Person.create
person.articles.create
person.articles.create
head :ok
end
# routet from GET /b, is basically a noop, (Articles are linked already), but
# causes problems when classes got reloaded! (so hit at least twice after a fresh start)
def assing_articles_another_time
person = Person.first
person.attributes = { :articles => Article.all }
person.save
head :ok
end
end
Hitting /b after /a results in the following exception where sqlite complains over the already existing join record. DataMapper tries to create the join records, where it should not.
mbj@seon ~/devel/bugapp $ rake db:automigrate
(in /home/mbj/devel/bugapp)
[datamapper] Finished auto_migrate! for :default repository '/home/mbj/devel/bugapp/db/development.sqlite3'
mbj@seon ~/devel/bugapp $ ./script/rails s -p 4003
=> Booting WEBrick
=> Rails 3.0.0.rc application starting in development on http://0.0.0.0:4003
=> Call with -d to detach
=> Ctrl-C to shutdown server
[datamapper] Setting up the "development" environment:
[datamapper] Setting up :default repository: '/home/mbj/devel/bugapp/db/development.sqlite3' on sqlite3
[2010-08-10 23:00:02] INFO WEBrick 1.3.1
[2010-08-10 23:00:02] INFO ruby 1.9.2 (2010-07-11) [x86_64-linux]
[2010-08-10 23:00:02] INFO WEBrick::HTTPServer#start: pid=2919 port=4003
Started GET "/a" for 93.131.158.195 at 2010-08-10 23:00:14 +0200
Processing by ApplicationController#create_person_and_articles as HTML
SQL (38.603ms) INSERT INTO "people" DEFAULT VALUES
SQL (29.642ms) INSERT INTO "articles" DEFAULT VALUES
SQL (0.124ms) SELECT "article_id", "person_id" FROM "article_people" WHERE ("person_id" = 1 AND "article_id" = 1) ORDER BY "article_id", "person_id" LIMIT 1
SQL (6.635ms) INSERT INTO "article_people" ("article_id", "person_id") VALUES (1, 1)
SQL (11.762ms) INSERT INTO "articles" DEFAULT VALUES
SQL (0.101ms) SELECT "article_id", "person_id" FROM "article_people" WHERE ("person_id" = 1 AND "article_id" = 2) ORDER BY "article_id", "person_id" LIMIT 1
SQL (7.455ms) INSERT INTO "article_people" ("article_id", "person_id") VALUES (2, 1)
Completed 200 OK in 150ms
Started GET "/b" for 93.131.158.195 at 2010-08-10 23:00:17 +0200
Processing by ApplicationController#assing_articles_another_time as HTML
SQL (0.079ms) SELECT "id" FROM "people" ORDER BY "id" LIMIT 1
SQL (0.137ms) SELECT "articles"."id" FROM "articles" INNER JOIN "article_people" ON "articles"."id" = "article_people"."article_id" INNER JOIN "people" ON "article_people"."person_id" = "people"."id" WHERE "article_people"."person_id" = 1 GROUP BY "articles"."id" ORDER BY "articles"."id"
SQL (0.034ms) SELECT "id" FROM "articles" ORDER BY "id"
columns article_id, person_id are not unique (code: 19, sql state: , query: INSERT INTO "article_people" ("article_id", "person_id") VALUES (1, 1), uri: sqlite3:///home/mbj/devel/bugapp/db/development.sqlite3)
Completed in 13ms
DataObjects::IntegrityError (columns article_id, person_id are not unique):
app/controllers/application_controller.rb:14:in `assing_articles_another_time'
Setting cache_classes = true, eliminates the problem. Running in rails console also. I'd expect the bug somewhere in the model reload code.
Note about running my example bugapp, you need to use dm-rails from git://github.com/datamapper/dm-rails, see Gemfile. dm-rails-1.0.0 from rubyforge is not yet compatible with rails3.
If you feel this bugreport would fit better in another bugtracker (like rails one under rails.lighthouseapp.com) please let me know I will post this issue there.
ruby -v
ruby 1.9.2dev (2010-07-11 revision 28618) x86_64-linux
Created by mbj - 2010-08-10 21:49:08 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1385
I have isolated a problem with rails3 and many 2 many associations in this sample rails3 app: git://github.com/mbj/bugapp
It is NOT reproducible under a non rails3 cache_classes = false environment.
The app is featuring two models:
One Controller:
Hitting /b after /a results in the following exception where sqlite complains over the already existing join record. DataMapper tries to create the join records, where it should not.
Setting cache_classes = true, eliminates the problem. Running in rails console also. I'd expect the bug somewhere in the model reload code.
Note about running my example bugapp, you need to use dm-rails from git://github.com/datamapper/dm-rails, see Gemfile. dm-rails-1.0.0 from rubyforge is not yet compatible with rails3.
If you feel this bugreport would fit better in another bugtracker (like rails one under rails.lighthouseapp.com) please let me know I will post this issue there.
ruby -v
ruby 1.9.2dev (2010-07-11 revision 28618) x86_64-linux
Created by mbj - 2010-08-10 21:49:08 UTC
Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1385