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

情到浓时终转凉″ 提交于 2019-12-03 21:59:11

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