DataMapper Associations - ruby

I was just trying to create a database with DataMapper. I am trying to associate the class User with class Post, Post2, Post3 and Post4. And I didnt get any message or changes in the Data SQLite Free, a database Mac application that I am using. Below is the code I created. Did I make any mistakes? Thanks!
require 'sinatra'
require 'data_mapper'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/wiki2.db")
class User
include DataMapper::Resource
property :id, Serial
property :username, Text, :required => true
property :password, Text, :required => true
property :date_joined, DateTime
property :edit, Boolean, :required => true, :default => false
has n, :posts
has n, :post2s
has n, :post3s
has n, :post4s
end
class Post
include DataMapper::Resource
property :id, Serial
property :content, Text
property :created_at, DateTime
property :updated_at, DateTime
belongs_to :user
end
class Post2
include DataMapper::Resource
property :id, Serial
property :content, Text
property :created_at, DateTime
property :updated_at, DateTime
belongs_to :user
end
class Post3
include DataMapper::Resource
property :id, Serial
property :content, Text
property :created_at, DateTime
property :updated_at, DateTime
belongs_to :user
end
class Post4
include DataMapper::Resource
property :id, Serial
property :content, Text
property :created_at, DateTime
property :updated_at, DateTime
belongs_to :user
end
DataMapper.finalize.auto_upgrade!

Related

DataMapper `has n` for different types of a model

I would like to have a model with different types of has n, for example:
class Blog
include DataMapper::Resource
property :id, Serial
has 1, :owner # of type user...
has n, :authors # of type user...
end
class User
include DataMapper::Resource
property :id, Serial
has n, :blogs # owns some number
has n, :blogs # is a member of some number
end
I don't, however, want to use the Discriminator, since then I need to make new Owner or Author objects of old User objects and that would be ridiculous.
How can I best achieve this?
Try this:
class User
include DataMapper::Resource
property :id, Serial
has n, :blog_authors, 'BlogAuthor'
has n, :authored_blogs, 'Blog', :through => :blog_authors, :via => :blog
has n, :blog_owners, 'BlogOwner'
has n, :owned_blogs, 'Blog', :through => :blog_owners, :via => :blog
end
class Blog
include DataMapper::Resource
property :id, Serial
has n, :blog_authors, 'BlogAuthor'
has n, :authors, 'User', :through => :blog_authors
has 1, :blog_owner, 'BlogOwner'
end
class BlogAuthor
include DataMapper::Resource
belongs_to :blog, :key => true
belongs_to :author, 'User', :key => true
end
class BlogOwner
include DataMapper::Resource
belongs_to :blog, :key => true
belongs_to :owner, 'User', :key => true
end

Data-Mapper Under passenger and ruby 1.8

My sinatra app is showing an error when declaring required on fields using datamapper running on passenger and ruby 1.8
error: undefined local variable or method `required' for Person:Class
class Person
include DataMapper::Resource
property :id, Serial
property :salutation, String
property :first_name, String , required => true
property :last_name, String , required => true
property :email, String , required => true, :format => :email_address
property :phone, String , required => true
property :dob, String
property :no_of_guests, String , required => true
property :attending, String, required => true
property :created_at, DateTime
end
Is this an issue with datamapper and ruby 1.8, or passenger or the way I'm decalring the required attribute?
requiredhas to be a symbol (:required):
class Person
include DataMapper::Resource
property :id, Serial
property :salutation, String
property :first_name, String , :required => true
property :last_name, String , :required => true
property :email, String , :required => true, :format => :email_address
property :phone, String , :required => true
property :dob, String
property :no_of_guests, String , :required => true
property :attending, String, :required => true
property :created_at, DateTime
end

Datamapper two associations at the same time

Lets say I have a post, this post should have a certian amount of comments, and these comments should be created by certian users. So these are my datamapper models:
class User
include DataMapper::Resource
property :id, Serial
property :name, String,
property :password, String
has n, :post
end
class Post
include DataMapper::Resource
property :id, Serial
property :text, Text
property :created_at, DateTime
belongs_to :user
end
class Comment
include DataMapper::Resource
property :text, Text,
property :created_at, DateTime
belongs_to :post
belongs_to :user
end
So let's say user x creates a post and user y wants to create a comment to this post. How do I do this then? I need something like this:
user = User.get(sessions[:user_id])
post = Post.get(params[:post_id])
comment = post.user.Comment.new {
:text => "Bla",
[...]
}
[...]
comment.save
[...]
So basicly the Model Post should be associated with the Model Comment and the Model Post, how do I realize this?
comment = Comment.create :post => post, :user => user, :text => 'Foo'

Don't work behaviors in Datamapper

I work with Sinatra. This is my models.
class Post
include DataMapper::Resource
property :id, Serial
property :title, String
property :body, Text
property :posted, Boolean, :default => true
has n, :comments
has n, :tags
end
class Comment
include DataMapper::Resource
property :id, Serial
property :user, String
property :body, Text
property :posted, Boolean, :default => false
belongs_to :post
end
class Tag
include DataMapper::Resource
property :id, Serial
property :tag, String
property :weight, Integer, :default => 1
belongs_to :post
end
Create a post
tags = params[:tags].split(' ')
post = Post.new(:title=>params[:title],:body=>params[:body])
tags.each { |tg|
post.tags << Tag.create(:tag=>tg)
}
redirect '/admin' if post.save
But no tags. What do I need to fix?
If you use one-to-many relation, you should create tags with :post set to post:
tags.each { |tg|
Tag.create(:tag => tg, :post => post)
}

Validate uniqueness on combined fields in DataMapper

I want to be able to put entries in my database where the manufacturer will be represented multiple times but not the same combination of manufacturer and model.
So "Sony(manufacturer), Tv(model)" is okay "Sony(manufacturer), OtherTv(model)" but the third entry "Sony(manufacturer), Tv(model)" is not okay since the combination of manufacturer and model is not unique. I tried with the :key => true validation but it doesn't seem to work. And I cannot do something like validates_uniqueness_of :manufacturer AND :model I guess. So how do you do it?
class Tvs
include DataMapper::Resource
property :id, Serial
property :manufacturer, String, :key => true
property :model, String, :key => true
validates_uniqueness_of :
end
You can actually go with:
class Tvs
include DataMapper::Resource
property :id, Serial
property :manufacturer, String, :unique_index => :manufacturer_model
property :model, String, :unique_index => :manufacturer_model
validates_uniqueness_of :model, :scope => :manufacturer
end
This will also give you a unique index in the database.
Nevermind.
It seems this did the job:
class Tvs
include DataMapper::Resource
property :id, Serial
property :manufacturer, String, :unique_index => true
property :model, String, :unique_index => true
validates_uniqueness_of :model, :scope => :manufacturer
end
class Tvs
include DataMapper::Resource
property :id, Serial
property :manufacturer, String, :unique_index => :manufacturer_model
property :model, String, :unique_index => :manufacturer_model
validates_is_unique :model, :scope => :manufacturer
end
I needed to modify the example to use "validates_is_unique" to get this to work.
If you remove the property :id Serial line, you will end up with a composite key (Manufacturer, Model), that will not allow duplicate Models for a particular Manufacturer.

Resources