Reputation: 448
I have an app that has a search box where you input a Twitter username and it returns the recent mentions of that user. https://hurrier-app.herokuapp.com/
Some tweets have an image associated with them. I need to be able to "favourite" an image and then be able to view all of them on a separate page.
I am very new to Rails so I was thinking of adding an array fav_pics
to the user model and appending each photo's url to it upon favouriting it. not sure where to start.
here's my user.rb
class User < ActiveRecord::Base
def self.from_omniauth(auth)
user = where(provider: auth.provider, uid: auth.uid).first || create_from_omniauth(auth)
user.oauth_token = auth["credentials"]["token"]
user.oauth_secret = auth["credentials"]["secret"]
user.save!
user
end
def self.create_from_omniauth(auth)
create! do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.name = auth["info"]["nickname"]
end
end
def twitter
if provider == "twitter"
@twitter ||= Twitter::Client.new(oauth_token: oauth_token, oauth_token_secret: oauth_secret)
end
end
has_many :fav_pics
has_many :pics_favorited,
class_name: 'Pic',
through: :fav_pics
end
class FavPic < ActiveRecord::Base
belongs_to :user
belongs_to :pic
end
class Pic < ActiveRecord::Base
has_many :fav_pics
has_many :fav_users,
class_name: 'User',
through: :fav_pics
end
now how do I actually handle the "favourite" event? I have experience with Meteor (javascript) but I am not sure how to handle events in Rails. Any resource links would be much appreciated.
Upvotes: 0
Views: 46
Reputation: 211750
That's the right idea. What you're describing is a join relationship, where to models are related by a third that pairs them.
For example:
class User
has_many :fav_pics
has_many :pics_favorited,
class_name: 'Pic',
through: :fav_pics
end
class FavPic
belongs_to :user
belongs_to :pic
end
class Pic
has_many :fav_pics
has_many :fav_users,
class_name: 'User',
through: :fav_pics
end
That's generally the key here. Normally the middle table has a compound index on user_id
and pic_id
with a UNIQUE
constraint so people can't favorite twice.
Using array-type columns, especially when they're not natively supported by your database, becomes extremely expensive and difficult to work with. Manipulating them requires re-writing the entire user record, so as people favorite more images the cost of an update increases. Likewise, finding all users that have favourited an image is computationally expensive to reverse.
If you're using an RDBMS, structuring it with conventional tables is usually the best plan.
Upvotes: 4