Reputation: 983
I have an object called a tag
which has_many :tweets
. The tweet
also has a corresponding belongs_to
.
If I'm generating a tweet to save in the tag
model like so:
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
How do I set that tweets parent to be the current tag? Would I do something like this?
new_tweet.tag = self
I tried this and it didn't work, whats a better solution? Thanks for your help.
Upvotes: 1
Views: 87
Reputation: 7366
Try create tweet's new object with association and tag_id will automatically assign in your new tweet object. So change Tweet.new
to self.tweets.new
and you are done.
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
As per your comment. You also have database structure issue. You need to resolve that first.
You don't have tag_id
in your tweets
table assuming you take tag name column. To make my code work properly and create a proper parent child relation you must have parent_id in your child table.
So try add tag_id
in your tweets
table and your error will gone. Also your value will save properly.
Upvotes: 1
Reputation: 76784
I think there's a better way to do it.
If you're saving a tag
object, why not just use an after_create
hook to make another tweet? You're basically copying all the data over anyway...
For example:
#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
You can read more about Rails' clone method here.
--
Relational
Rails is actually very good with handling relational data.
Pavan in the comments is almost spot-on with his recommendation of using tag_id
. This, of course, will load a database attribute, but there's a better way.
As can be seen here, there are a number of methods added with a has_many/belongs_to
relationship:
This means you'll be able to use the following:
tweet.tag
to retrieve the tag object.
If tweet
had many tag
, you'd be able to use the tweet.tag
or
tweet.tag_id
All of this means you can pass an object to your new_tweet.tag
attribute...
Thus, your answer:
new_tweet.tag = tweet.tag
Upvotes: 0
Reputation: 1949
I'd say you have two solutions :
1) As suggested by pavan, assign the tag_id of the original tweet to the new tag. This will create the association between new_tweet
and the tag :
new_tweet.tag_id = tweet.tag_id
2) Or, if you do create the new_tweet
in a tag instance method, you can directly create the tweet through the association as suggested by Dipak :
new_tweet = self.tweets.build
Upvotes: 0