User to mark (favorite-like) another Model in Ruby on Rails

ぐ巨炮叔叔 提交于 2019-12-05 07:42:20

问题


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.


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!