我有一个Comment
对象,在Tag
关联中可以有许多has_and_belongs_to_many
个与之关联的对象。在创建时,我希望注释包含与其关联的标记,希望无需进行单独的查询。怎么办呢?
修改:
为了帮助澄清我的问题,这是我的评论创建控制器方法:
def create
@comment = @current_user.comment!(@post, comment_params[:content])
render :show, status: :created
end
这是我的comment!
方法:
def comment!(yum, content)
comment = comments.create!(yum_id: yum.id, content: content)
comment.create_activity :create, owner: self, recipient: yum.user
mentions = content.scan(/\@\w+/)
for mention in mentions
if mentioned_user = User.find_by_username(mention.sub("@", ""))
mention!(mentioned_user, comment)
end
end
comment
end
这是检查保存前执行的标签文本的方法:
def create_tags
tags = content.scan(/\#[[:alnum:]]+/)
for tag in tags
tag = tag.sub("#", "")
if found_tag = Tag.find_by_content(tag.downcase)
self.tags << found_tag
else
self.tags.build(content: tag)
end
end
end
这是我的jbuilder评论观点:
json.extract! comment, :id, :content, :created_at, :updated_at
json.tags comment.tags do |tag|
json.partial! 'api/v1/shared/tag', tag: tag
end
json.user do |json|
json.partial! 'api/v1/shared/user', user: comment.user
end
我想要的是在创建评论时要包含的标签(并且提到了它,但是解决一个解决了另一个)。当我只是显示那些已经包含的评论时,它在创建时只返回评论。
答案 0 :(得分:0)
如果我正确理解了这个问题,可以通过覆盖Comment对象的as_json
方法来解决这个问题。
# in Comment.rb
def as_json(options = nil)
super( (options || {}).merge({
include: :tags
})
end
这应该确保当注释呈现为JSON时,哈希还包含tags
关联。当您在ActiveRecord对象上调用as_json
时,会调用to_json
方法 - 有关更详细的说明,请参阅this出色的答案或as_json
方法的文档{ {1}} here。
如果我误解了你的问题,请告诉我! : - )
答案 1 :(得分:0)
试试这个:
def create
@comment = @current_user.comment!(@post, comment_params[:content])
render json: @comment.to_json( include: :tags ), status: :created, location: @comment
end
答案 2 :(得分:0)
您需要使用where
子句过滤Tag对象:
替换:
tags = content.scan(/\#[[:alnum:]]+/)
for tag in tags
tag = tag.sub("#", "")
if found_tag = Tag.find_by_content(tag.downcase)
self.tags << found_tag
else
self.tags.build(content: tag)
end
end
使用:
sent_tags = content.scan(/#([[:alnum:]]+)/).flatten.map &:downcase
self.tags = Tag.where(content: tags) # This is the line that saves multiple queries
new_tags = sent_tags - tags.map(&:content)
new_tags.each do |new_tag|
self.tags.build(content: new_tag)
end
注意:
2.1.2 :016 > "some #Thing #qwe".scan(/#([[:alnum:]]+)/).flatten.map &:downcase
=> ["thing", "qwe"]
sent_tags
会根据您的需要存储代码。