1

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                                                                                                                 
Alo Sarv
  • 376
  • 3
  • 4

0 Answers0