Don*_*ano 5 ruby datamapper sinatra
好吧,这让我发疯了.我已经阅读了协会的文章和例子,并试图在拉斯三天内解决这个问题,我厌倦了这让我感到愚蠢,所以......
如何设置与DataMapper的关联?
(我正在使用带有SQLite3的带有Sinatra的DM.对于具有多个值等的单个表,一切都很好.当我开始尝试将它们关联起来时,我开始收到错误.)
假设我有一个装满苹果树的果园.每棵树都有很多苹果.每个Apple都有很多种子.因此每棵树通过其苹果有很多种子
require 'sinatra'
require 'datamapper'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/orchard.db")
# Trees in the orchard.
class Tree
include DataMapper::Resource
property :id, Serial
has n, :apples
has n, :seeds, :through => :apples
end
# Apples on a Tree.
class Apple
include DataMapper::Resource
property :id, Serial
belongs_to :tree
belongs_to :seed
end
# Seeds in an Apple
class Seed
include DataMapper::Resource
property :id, Serial
has n, :apple
has n, :tree, :through => apple
end
DataMapper.finalize.auto_upgrade!
Run Code Online (Sandbox Code Playgroud)
那是对的吗?我尝试运行时遇到各种错误.大多数沿着无效关联的行或者不能创建值为NULL的列NULL等.我不理解这种关系?
此外,一旦我有了工作模型,我该如何从中获取信息?
如果有3棵树:
Tree.all.count
=> 3
Run Code Online (Sandbox Code Playgroud)
如果有2个苹果:
Apple.all
=>[#<Apple @id=1>, #<Apple @id=2>]
Run Code Online (Sandbox Code Playgroud)
好的.但树#2有多少苹果?Tree#4有多少种子?总共有多少苹果?总共有多少种子?
任何帮助将不胜感激.
mat*_*att 12
你的模型似乎有点困惑:
假设我有一个装满苹果树的果园.每棵树都有很多苹果.每个Apple都有很多种子.因此每棵树通过其苹果有很多种子.
因此,一棵树有许多苹果,一棵苹果属于一棵树,有许多种子,种子属于苹果(最终是一棵树).
我们几乎(但不完全)可以使用该语言并使用它来创建关联.经过一点点翻译以获得正确的语法,我们得到了这个:
# Trees in the orchard.
class Tree
include DataMapper::Resource
property :id, Serial
has n, :apples # "a tree has many apples"
has n, :seeds, :through => :apples
end
# Apples on a Tree.
class Apple
include DataMapper::Resource
property :id, Serial
belongs_to :tree # "an apple belongs to a tree..."
has n, :seeds # "...and has many seeds"
end
# Seeds in an Apple
class Seed
include DataMapper::Resource
property :id, Serial
belongs_to :apple # "and a seed belongs to an apple"
end
Run Code Online (Sandbox Code Playgroud)
在你的代码中你有多个苹果和树木的种子,这没有任何意义.
至于查询:
但树#2有多少苹果?
假设你指的是Tree具有id == 2:
tree_2 = Tree.get(2)
apples_of_tree_2 = tree_2.apples # this gives an array of apples
count_of_apples_of_tree_2 = tree_2.apples.count
Run Code Online (Sandbox Code Playgroud)
Tree#4有多少种子?
我们添加到Tree模型中的关联has n, :seeds, :through => :apples意味着我们seeds在Tree对象中有一个可用的方法.
Tree.get(4).seeds.count
Run Code Online (Sandbox Code Playgroud)
总共有多少苹果?总共有多少种子?
只是:
Apple.count # note singular not plural (it's a class method on Apple)
Seed.count
Run Code Online (Sandbox Code Playgroud)
尝试将这个新模型加载到irb中(您可能需要orchard.db在更改模型时删除文件),然后使用一些查询和创建方法,希望这会让您更好地了解正在发生的事情.
要将现有内容添加Apple到Tree:
a_tree.apples << an_apple
Run Code Online (Sandbox Code Playgroud)
请注意,a Tree与单个Apple而不是集合(it has n Apples)无关,因此创建的方法是apples(即它是多元化的),并且没有方法apple可以解释为什么你看到no方法错误.
您还可以直接创建Apple与之关联的新内容Tree:
a_tree.apples.new #created but not saved to database
a_tree.apples.create #created and saved to database
Run Code Online (Sandbox Code Playgroud)
您也可以从Apple侧面创建相反的关联:
an_other_apple = Apple.new
an_other_apple.tree = a_tree
Run Code Online (Sandbox Code Playgroud)
但是你需要小心这样做,因为新的苹果不会出现在(不包括)a_tree的集合中.为了它出现您需要保存的苹果,然后调用上:Applesa_tree.applesan_other_applereloadTree
an_other_apple.save
a_tree.reload
Run Code Online (Sandbox Code Playgroud)
你需要注意这一点,因为如果你不小心的话,你可能会在同一时间看到Apple两个Trees.