Ell*_*iot 5 ruby-on-rails ruby-on-rails-3
继承人我正在努力实现的目标:
我想检查标签是否已存在.如果是这样,我想使用tag_join记录的现有标记,而不是创建新的标记记录.
这是我当前的代码,它不起作用.
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
Run Code Online (Sandbox Code Playgroud)
这不起作用,我在创建任务时遇到错误...(服务器实际上只是超时 - 我没有收到特定的错误).
有任何想法吗?
Tokland说我通过告诉它再次创建标签来创建一个无限循环 - 所以我尝试了这个:
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
Run Code Online (Sandbox Code Playgroud)
仍然得到服务器超时
编辑:我不确定这是否重要,但标签的添加方式类似于"http://railscasts.com/episodes/73-complex-forms-part-1
它们嵌套在帖子中,并使用类似这样的东西:
def tag_attributes=(tag_attributes)
tag_attributes.each do |attributes|
tags.build(attributes)
end
end
Run Code Online (Sandbox Code Playgroud)
我想知道这是否会阻止整个工作?此外,在模型中使用current_user.id肯定是个问题...
编辑:
我已经想到的东西:这必须改变,我们以前使用的格式是不正确的语法 - 通常用于.where方法.
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
Run Code Online (Sandbox Code Playgroud)
现在的问题是,我可以知道标签是否已经存在.但那又怎样?如果我使用return false选项,则在创建帖子时会出现错误,并且不会创建连接记录...其他选项"self = @ tag"显然不起作用.
zet*_*tic 12
你会发现很难从Tag模型中找到它.看起来你想要的是使用嵌套属性更新Post,如下所示:
post = Post.create
post.update_attributes(:tags_attributes=>{"0"=>{:name=>"fish",:user_id=>"37"}})
Run Code Online (Sandbox Code Playgroud)
使用虚拟属性setter方法实际上很简单:
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
Run Code Online (Sandbox Code Playgroud)
find_or_create_by_Rails内置了一个功能
# No 'Summer' tag exists
Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
# Now the 'Summer' tag does exist
Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
Run Code Online (Sandbox Code Playgroud)
http://api.rubyonrails.org/classes/ActiveRecord/Base.html(在基于动态属性的查找程序下)
你想使用魔术方法 find_or_create_by
def check_exists
tag = Tag.find_or_create_by_name_and_user_id(:name => self.name, :user_id => current_user.id)
end
Run Code Online (Sandbox Code Playgroud)
查看ActiveRecord :: Base文档以获取更多信息
我最初提出的问题到最后变得非常扭曲。所以我要把它分开。
试图做我最初要求的人可以试试这个:
before_create :check_tag_exists
private
def check_tag_exists
@tag = Tag.find_by_name_and_user_id(self.name, self.user_id)
if @tag != nil
#
end
end
Run Code Online (Sandbox Code Playgroud)
这将使您能够检查您的记录是否已经创建。您可以添加任何进一步的逻辑 if 语句。
| 归档时间: |
|
| 查看次数: |
28429 次 |
| 最近记录: |