I want to implement a "Read Later" (just like Favorites) system in a Ruby on Rails app. What I want is for a User
model to be able to mark a Content
model to read later.
My associations between the two models are like this:
class User < ActiveRecord::Base
has_many :contents
end
-------------
class Content < ActiveRecord::Base
belongs_to :user
end
Then a Content belongs to a Category
, etc, but that doesn't matter for the question so I just didn't put it there.
A User
can mark a Content
(that could belong to another user) and there will be a list of "marked contents (to read later)" for each user.
How could I implement this?
I've already read this question but I didn't really understand and when trying to simulate it, it didn't work.
What did you try and what didn't work?
This is pretty straight forward. Let us think through:
There is a User:
class User < ActiveRecord::Base
end
There is Content:
class Content < ActiveRecord::Base
end
A User can create Content and is he restricted to create only one content? no. A User can create as many contents as he wants. This is to say in Rails terms a User has_many
contents. To put this in other words, can we say that a Content is created by a User.
class User < ActiveRecord::Base
has_many :contents
end
class Content < ActiveRecored::Base
belongs_to :user
end
Now, the content (typically created by other users) can be favorited (marked as 'Read Later') by other users. Each User can favorite (mark 'Read Later') as many contents as he wants and each Content can be favorited by many users isn't it? However, we'll have to track which User favorited which Content somewhere. The easiest would be to define another model, let us say MarkedContent, to hold this information. A has_many :through association is often used to set up a many-to-many connection with another model. So the relevant association declarations could look like this:
class User < ActiveRecord::Base
has_many :contents
has_many :marked_contents
has_many :markings, through: :marked_contents, source: :content
end
class MarkedContent < ActiveRecord::Base
belongs_to :user
belongs_to :content
end
class Content < ActiveRecord::Base
belongs_to :user
has_many :marked_contents
has_many :marked_by, through: :marked_contents, source: :user
end
Now you can do:
user.contents # to get all the content created by this user
user.marked_contents # to get all the contents marked as 'Read Later' by this user
content.user # to get the creator of this content
content.marked_by # to get all the users who have marked this content
Read more here to learn about associations.
To mark a content as a favorite, one way would be:
@user = User.first
@content = Content.last
@user.markings << @content
You can also implement a method in the User model to do this for you:
class User < ActiveRecord::Base
...
def read_later(content)
markings << content
end
end
Now, you can do:
@user.read_later(@content)
来源:https://stackoverflow.com/questions/24305570/user-to-mark-favorite-like-another-model-in-ruby-on-rails