I am trying to create a set of models to express Posts and Users where Users author posts and can also Like posts. The following code seems to produce the right set of SQL tables, however the last lookup fails because of conflict in User :posts key - but all of my attempts to rename it have failed/broken the schema.
How do I rename the last :posts in User (for likes) to :post_likes without breaking anything else?
require 'data_mapper'
require 'dm-sqlite-adapter'
require 'dm-noisy-failures'
DataMapper::Logger.new($stdout, :debug)
DataMapper::setup(:default, 'sqlite::memory:')
class Post
include DataMapper::Resource
belongs_to :author, 'User', :child_key => :author_id
property :id, Serial, :key => true
property :message, Text
has n, :post_likes
has n, :users, :through => :post_likes
end
class User
include DataMapper::Resource
property :id, Serial, :key => true
property :name, String
has n, :posts, :via => :author
has n, :post_likes
has n, :posts, :through => :post_likes # rename this to :post_likes
end
class PostLike
include DataMapper::Resource
belongs_to :post, :key => true
belongs_to :user, :key => true
end
DataMapper.finalize
DataMapper.auto_migrate!
john = User.first_or_create(:name => 'John')
hello = Post.create(:message => 'Hello', :author => john)
tony = User.create(:name => 'Tony')
fav = PostLike.create(:user => tony, :post => hello)
puts tony.post_likes.first.post.to_json # OK
puts hello.post_likes.first.user.to_json # OK
puts Post.first(:author => john).to_json # OK
puts john.posts.first.to_json # fails (tries to look up via likes)
Last two queries (2nd should be same as 1st):
~ (0.000000) SELECT "id", "message" FROM "posts" WHERE "id" = 1 ORDER BY "id"
{"id":1,"message":"Hello","author_id":1}
~ (0.000998) SELECT "posts"."id", "posts"."author_id" FROM "posts" INNER JOIN
"post_likes" ON "posts"."id" = "post_likes"."post_id" INNER JOIN
"users" ON "post_likes"."user_id" = "users"."id" WHERE
"post_likes"."user_id" = 1 GROUP BY "posts"."id", "posts"."author_id"
ORDER BY "posts"."id" LIMIT 1
null