Sinatra:关联具有 DataMapper 一对多关系的 class 实例时出现问题
Sinatra: Trouble with associating class instances having DataMapper One-To-Many-Through relation
我正在尝试为 cms 构建管理后端。我有几个型号 classes,其中两个是 Post
和 Tag
。他们相连 through
Tagging
class。
Post 型号
class Post
include DataMapper::Resource
property :id, Serial
property :title, String, :required => true
property :body, Text, :required => true
property :is_blog_post, Boolean, :default => true
property :viewed, Integer, :default => 0
property :featured, Boolean, :default => false
property :created_at, DateTime
property :updated_at, DateTime
belongs_to :author
belongs_to :category
has n, :comments
has n, :taggings
has n, :tags, :through => :taggings
#some other methods
end
标签模型
class Tag
include DataMapper::Resource
property :id, Serial
property :name, String, :unique =>true
has n, :taggings
has n, :posts, :through => :taggings
#some methods
end
标记
class Tagging
include DataMapper::Resource
belongs_to :tag, :key => true
belongs_to :post, :key => true
end
来自routes.rb的相关代码创建post ()
get '/articles/new' do
@cats = Category.all
@article = Post.new
erb :post_form
end
post '/articles' do
@article = Post.create(
:title => params[:title],
:body => params[:body],
:featured => params[:featured],
:category_id =>params[:category_id],
:author_id => session[:user].id,
:is_blog_post => false
)
taginputs = params[:tags]
taginputs.split(", ").each do |newtag|
nt = Tag.first_or_create(:name=> newtag)
@article.tags << nt
end
if @article.saved?
redirect to ('/articles')
else
redirect to ("/articles/new")
end
end
这是post_form.erb部分
<div style="margin-left:50px;">
<legend>New article</legend>
<div class="alert alert-info" role="alert">
<p> <!-- flash notice will be here --> </p>
</div>
<form action='/articles' method="post">
<div class="form-group">
<p><label>Title</label></p>
<input type="text" name="title" value="<%= @article.title unless @article.title.nil? %>">
</div>
<div class="form-group">
<p><label>Body</label></p>
<textarea name="body"><%= @article.body unless @article.body.nil? %></textarea>
</div>
<% if session[:user].is_admin? %>
<div class="form-group">
<input type="radio" name="featured" value="1"><p>Featured</p>
<input type="radio" name="featured" value="0"><p>Ordinary</p>
</div>
<% end %>
<div class="form-group">
<input type="text" name="tags" value="<%= @article.post_tags unless @article.post_tags.nil?%>">
</div>
<div class="form-group">
<select name="category_id">
<% @cats.each do |cat|%>
<option value="<%= cat.id %>"><%= cat.name %></option>
<% end %>
</select>
</div>
<div class="form-group">
<input type="submit" value="Submit">
</div>
</form>
</div>
当我提交表单时,它会按我的预期创建 Post
实例。它还能很好地创建 Tag
个实例。但它没有将 tags
与那篇文章相关联。
当我在 irb
、
中测试相同的逻辑(当然是根据我的)
2.2.0 :002 > p8 = Post.get(8)
=> #<Post @id=8 @title="What is lorem ipsum?" @body=<not loaded> @is_blog_post=true @viewed=0 @featured=false @created_at=#<DateTime: 2015-08-02T23:11:31+05:00 ((2457237j,65491s,0n),+18000s,2299161j)> @updated_at=#<DateTime: 2015-08-02T23:11:31+05:00 ((2457237j,65491s,0n),+18000s,2299161j)> @author_id=1 @category_id=1>
2.2.0 :003 > sometags = "Lorem Ipsum, Lorem, Ipsum, Dolores, O'Riordan"
=> "Lorem Ipsum, Lorem, Ipsum, Dolores, O'Riordan"
2.2.0 :004 > sometags.split(", ").each do |newtags|
2.2.0 :005 > nt = Tag.first_or_create(:name => newtags)
2.2.0 :006?> p8.tags << nt
2.2.0 :007?> end
=> ["Lorem Ipsum", "Lorem", "Ipsum", "Dolores", "O'Riordan"]
2.2.0 :008 > p8.tags
=> [#<Tag @id=29 @name="Lorem Ipsum">, #<Tag @id=30 @name="Lorem">, #<Tag @id=31 @name="Ipsum">, #<Tag @id=32 @name="Dolores">, #<Tag @id=34 @name="O'Riordan">]
它也有效。
我是不是遗漏了什么?
幸运的是我刚刚看到,我忘记为新创建的 Post
实例调用 save!
方法。在 @article.tags << nt
之后添加 @article.save!
...
@article.tags << nt
@article.save!
end
...
现在好了:)
我正在尝试为 cms 构建管理后端。我有几个型号 classes,其中两个是 Post
和 Tag
。他们相连 through
Tagging
class。
Post 型号
class Post
include DataMapper::Resource
property :id, Serial
property :title, String, :required => true
property :body, Text, :required => true
property :is_blog_post, Boolean, :default => true
property :viewed, Integer, :default => 0
property :featured, Boolean, :default => false
property :created_at, DateTime
property :updated_at, DateTime
belongs_to :author
belongs_to :category
has n, :comments
has n, :taggings
has n, :tags, :through => :taggings
#some other methods
end
标签模型
class Tag
include DataMapper::Resource
property :id, Serial
property :name, String, :unique =>true
has n, :taggings
has n, :posts, :through => :taggings
#some methods
end
标记
class Tagging
include DataMapper::Resource
belongs_to :tag, :key => true
belongs_to :post, :key => true
end
来自routes.rb的相关代码创建post (
get '/articles/new' do
@cats = Category.all
@article = Post.new
erb :post_form
end
post '/articles' do
@article = Post.create(
:title => params[:title],
:body => params[:body],
:featured => params[:featured],
:category_id =>params[:category_id],
:author_id => session[:user].id,
:is_blog_post => false
)
taginputs = params[:tags]
taginputs.split(", ").each do |newtag|
nt = Tag.first_or_create(:name=> newtag)
@article.tags << nt
end
if @article.saved?
redirect to ('/articles')
else
redirect to ("/articles/new")
end
end
这是post_form.erb部分
<div style="margin-left:50px;">
<legend>New article</legend>
<div class="alert alert-info" role="alert">
<p> <!-- flash notice will be here --> </p>
</div>
<form action='/articles' method="post">
<div class="form-group">
<p><label>Title</label></p>
<input type="text" name="title" value="<%= @article.title unless @article.title.nil? %>">
</div>
<div class="form-group">
<p><label>Body</label></p>
<textarea name="body"><%= @article.body unless @article.body.nil? %></textarea>
</div>
<% if session[:user].is_admin? %>
<div class="form-group">
<input type="radio" name="featured" value="1"><p>Featured</p>
<input type="radio" name="featured" value="0"><p>Ordinary</p>
</div>
<% end %>
<div class="form-group">
<input type="text" name="tags" value="<%= @article.post_tags unless @article.post_tags.nil?%>">
</div>
<div class="form-group">
<select name="category_id">
<% @cats.each do |cat|%>
<option value="<%= cat.id %>"><%= cat.name %></option>
<% end %>
</select>
</div>
<div class="form-group">
<input type="submit" value="Submit">
</div>
</form>
</div>
当我提交表单时,它会按我的预期创建 Post
实例。它还能很好地创建 Tag
个实例。但它没有将 tags
与那篇文章相关联。
当我在 irb
、
2.2.0 :002 > p8 = Post.get(8)
=> #<Post @id=8 @title="What is lorem ipsum?" @body=<not loaded> @is_blog_post=true @viewed=0 @featured=false @created_at=#<DateTime: 2015-08-02T23:11:31+05:00 ((2457237j,65491s,0n),+18000s,2299161j)> @updated_at=#<DateTime: 2015-08-02T23:11:31+05:00 ((2457237j,65491s,0n),+18000s,2299161j)> @author_id=1 @category_id=1>
2.2.0 :003 > sometags = "Lorem Ipsum, Lorem, Ipsum, Dolores, O'Riordan"
=> "Lorem Ipsum, Lorem, Ipsum, Dolores, O'Riordan"
2.2.0 :004 > sometags.split(", ").each do |newtags|
2.2.0 :005 > nt = Tag.first_or_create(:name => newtags)
2.2.0 :006?> p8.tags << nt
2.2.0 :007?> end
=> ["Lorem Ipsum", "Lorem", "Ipsum", "Dolores", "O'Riordan"]
2.2.0 :008 > p8.tags
=> [#<Tag @id=29 @name="Lorem Ipsum">, #<Tag @id=30 @name="Lorem">, #<Tag @id=31 @name="Ipsum">, #<Tag @id=32 @name="Dolores">, #<Tag @id=34 @name="O'Riordan">]
它也有效。
我是不是遗漏了什么?
幸运的是我刚刚看到,我忘记为新创建的 Post
实例调用 save!
方法。在 @article.tags << nt
@article.save!
...
@article.tags << nt
@article.save!
end
...
现在好了:)