【问题标题】:Setting a 'has_many's object to carry it's parent id设置一个'has_many'对象来携带它的父ID
【发布时间】:2015-09-23 04:31:22
【问题描述】:

我有一个名为tag 的对象has_many :tweetstweet 也有对应的belongs_to

如果我要生成一条推文以保存在 tag 模型中,如下所示:

        new_tweet = Tweet.new

        new_tweet.favorite_count = tweet.favorite_count 
        new_tweet.filter_level = tweet.filter_level 
        new_tweet.retweet_count = tweet.retweet_count 
        new_tweet.text = tweet.text 
        new_tweet.tweeted_at = tweet.created_at 

        new_tweet.created_at = DateTime.strptime tweet.created_at.to_s, '%Y-%m-%d %H:%M:%S %z' 

        new_tweet.save 

如何将 tweets 父级设置为当前标签?我会做这样的事情吗?

new_tweet.tag = self

我试过了,但没有用,有什么更好的解决方案?谢谢你的帮助。

【问题讨论】:

  • 如果tweet 包含tag_id 那么new_tweet.tag_id = tweet.tag_id 应该可以工作
  • @Pavan - 您应该将此作为官方答案。
  • @miler350 我将等待 OP 的确认,然后再将其发布为答案 :)

标签: ruby-on-rails model has-many belongs-to


【解决方案1】:

尝试使用关联创建推文的新对象,tag_id 将自动分配到您的新推文对象中。所以将Tweet.new 更改为self.tweets.new 就完成了。

new_tweet = self.tweets.new

new_tweet.favorite_count = tweet.favorite_count 
new_tweet.filter_level = tweet.filter_level 
new_tweet.retweet_count = tweet.retweet_count 
new_tweet.text = tweet.text 
new_tweet.tweeted_at = tweet.created_at 

new_tweet.created_at = DateTime.strptime tweet.created_at.to_s, '%Y-%m-%d %H:%M:%S %z' 

new_tweet.save 

根据您的评论。您还有数据库结构问题。你需要先解决这个问题。 假设您使用标签名称列,您的tweets 表中没有tag_id。为了使我的代码正常工作并创建正确的父子关系,您的子表中必须有 parent_id。

所以尝试在您的tweets 表中添加tag_id,您的错误就会消失。您的价值也将正确保存。

【讨论】:

  • 因此,当我添加您建议 new_tweet = self.tweets.new 的这一行时,我收到此错误:ActiveRecord::UnknownAttributeError: unknown attribute 'tag_id' for Tweet.。知道为什么会这样吗?
  • 这里有数据库问题。您需要在 tweets 表中添加 tag_id。我也更新了我的答案。
  • 感谢修复。
【解决方案2】:

我想说你有两个解决方案:

1) 按照 pavan 的建议,将原始推文的 tag_id 分配给新标签。这将创建new_tweet 和标签之间的关联:

new_tweet.tag_id = tweet.tag_id

2) 或者,如果您确实在标签实例方法中创建new_tweet,您可以按照 Dipak 的建议通过关联直接创建推文:

new_tweet = self.tweets.build

【讨论】:

  • 第一种方式给了我一个错误。第二种方式给了我这个错误(我最初尝试它为new_tweet.tag = self,但它应该和你在建议一中得到的一样,都给我:ActiveModel::MissingAttributeError: can't write unknown attribute tag_id``。方式2给我和我一样的错误在下面的评论中提到:ActiveRecord::UnknownAttributeError: unknown attribute 'tag_id' for Tweet 所以也许我这里有更深层次的问题?
  • 您的数据库中是否有Tweet 模型的“tag_id”列?
【解决方案3】:

我认为有更好的方法。

如果您要保存 tag 对象,为什么不直接使用 after_create 挂钩来制作另一条推文?无论如何,您基本上是在复制所有数据...

例如:

#app/models/tag.rb
class Tag < ActiveRecord::Base
    has_many :tweets
    attr_accessor :parent
    #This will allow you to save a tag with attribute "parent" as true. If true, the tweet model will create another tweet. It will need tweaking
end

#app/models/tweet.rb
class Tweet < ActiveRecord::Base
   belongs_to :tag
   after_create :new_tweet, if: Proc.new { |tweet| tweet.tag.parent }

   def new_tweet
      new = self.clone
      new.tweeted_at = self.created_at
      new.created_at = DateTime.strptime self.created_at.to_s, '%Y-%m-%d %H:%M:%S %z' 
      new.save
   end
end

您可以在此处阅读有关Rails' clone method 的更多信息。

--

关系

Rails 实际上非常擅长处理关系数据。

cmets 中的 Pavan 几乎对他使用 tag_id 的建议非常准确。当然,这会加载数据库属性,但有更好的方法。

可以看到here,有很多方法添加了has_many/belongs_to关系:

这意味着您将能够使用以下内容:

  • tweet.tag 检索标签对象。

  • 如果tweet 有很多tag,您可以使用tweet.tagtweet.tag_id

所有这一切意味着您可以将对象传递给您的new_tweet.tag 属性...

因此,您的答案:

new_tweet.tag = tweet.tag

【讨论】:

    猜你喜欢
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    相关资源
    最近更新 更多