在rails3中创建新记录之前如何检查记录是否存在? [英] How to check if a record exists before creating a new one in rails3?
问题描述
这是我想要完成的:
- 我有一个标记系统.
- 创建帖子时创建标签(帖子 has_many :tags, :through => :tag_joins.
- 当使用标签创建帖子时,会自动创建标签连接).
我想检查标签是否已经存在.如果确实如此,我想将现有标签用于 tag_join 记录,而不是创建新的标签记录.
I want to check if the tag already exists. If it does I want to use the existing tag for the tag_join record, rather than creating a new tag record.
这是我当前的代码,它不起作用.
Here is my current code, which isn't working.
class Tag < ActiveRecord :: Base
belongs_to :user
belongs_to :tag_join
belongs_to :post
before_create :check_exists
def check_exists
tag = Tag.where(:name => self.name, :user_id => current_user.id)
if tag.nil?
tag = Tag.create(:name => self.name, :user_id => current_user.id)
end
end
end
但这不起作用,我在创建任务时遇到错误...(服务器实际上只是超时 - 我没有收到特定错误).
This doesn't work though, I'm getting an error upon task creation...(the server is actually just timing out - I don't receive a specific error).
有什么想法吗?
Tokland 说我通过告诉它再次创建标签来创建一个无限循环 - 所以我尝试了这个:
Tokland said I was creating an infinite loop by telling it to create tag again - so I tried this:
def check_exists
tag = Tag.find_by_name_and_user_id(:name => self.name, :user_id => current_user.id)
if tag != nil
self.id = tag.id
end
end
仍然得到服务器超时
我不确定这是否重要,但添加标签的方式类似于http://railscasts.com/episodes/73-complex-forms-part-1
I'm not sure if this matters, but the way the tags are being added is similar to "http://railscasts.com/episodes/73-complex-forms-part-1
它们嵌套在帖子表单中,并使用如下内容:
they're nested in the post form, and use something like this:
def tag_attributes=(tag_attributes)
tag_attributes.each do |attributes|
tags.build(attributes)
end
end
我想知道这是否会阻止整个工作?此外,在模型中使用 current_user.id 似乎肯定是一个问题...
I'm wondering if this is stopping this whole thing from working? Also, using current_user.id in the model definitely seems to be an issue...
我发现了一些东西:这必须改变,我们之前使用的格式是不正确的语法 - 通常用于 .where 方法.
Something I have figured out: this had to change, the format we were using before was incorrect syntax - generally used for a .where method.
def check_exists
@tag = Tag.find_by_name_and_user_id(self.name, self.user_id)
if @tag != nil
#return false
#self=@tag
end
end
现在的问题是,我可以知道标签是否已经存在.但是然后呢?如果我使用 return false 选项,则创建帖子时会出现错误,并且不会创建连接记录...另一个选项self=@tag"显然不起作用.
The problem now is this, I can learn if it the tag already exists. But then what? If I go with the return false option, there is an error upon post creation, and the join record isn't created... The other option "self=@tag" obviously just doesn't work.
推荐答案
您会发现很难从 Tag 模型中做到这一点.似乎您想要的是使用嵌套属性更新 Post,如下所示:
You're going to find it hard to to this from within the Tag model. It seems like what you want is to update the Post using nested attributes, like so:
post = Post.create
post.update_attributes(:tags_attributes=>{"0"=>{:name=>"fish",:user_id=>"37"}})
通过使用虚拟属性设置器方法,这实际上非常简单:
This is actually pretty simple to do by using a virtual attribute setter method:
class Post < AR::Base
has_many :tags
def tags_attributes=(hash)
hash.each do |sequence,tag_values|
tags << Tag.find_or_create_by_name_and_user_id(tag_values[:name],\
tag_values[:user_id])
end
end
> post = Post.create
> post.update_attributes(:tags_attributes=>{"0"=>{:name=>"fish",:user_id=>"37"}})
> Tag.count # => 1
# updating again does not add dups
> post.update_attributes(:tags_attributes=>{"0"=>{:name=>"fish",:user_id=>"37"}})
> Tag.count # => 1
这篇关于在rails3中创建新记录之前如何检查记录是否存在?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!