我的应用中有一个Post
模型,它有一个posts
属性,用于存储看起来像这样的JSON对象:
Post.last.posts = {
twitter: 'This is a tweet',
facebook: 'This is a facebook post'
}
用户创建一个Post
,然后将其发送到多个平台。这种架构对原始应用程序设计有意义。现在,我想让用户能够隐藏他们对一个平台发布的帖子,而不会影响其他平台的帖子。因为帖子是数据库中的单个模型,所以我需要找到一种解决方法。我不确定这是否是最佳方法,但我决定在User
模型和Post
模型之间创建一个连接表。请注意,帖子是由不同的用户模型(Admin
)创建的,而User
只是查看帖子。
以下是我的模特:
class Post < ActiveRecord::Base
has_many :post_users
has_many :users, through: :post_users
end
class User < ActiveRecord::Base
has_many :post_users
has_many :posts, through: :post_users
end
class PostUser < ActiveRecord::Base
belongs_to :post
belongs_to :user
delegate :hide_twitter, to: :post
delegate :hide_facebook, to: :post
def hide_twitter
self.hide_twitter
end
end
在我构建的视图中,每个Post
都表示为一系列卡片 - 每个平台一张卡片。因此,如果帖子在Twitter和Facebook上,它将显示为两个单独的卡 - 每个平台一个。我想要做的是让User
能够隐藏其中一张牌而不影响其他牌。由于Post
属于许多用户,因此必须是联接表的属性(例如PostUser
)。
我想知道的是,是否可以通过Post
模型访问联接表的此属性?我想做类似以下的事情,但我不确定它是否可行,或者我是否在联接表中使用delegate
采取了正确的方法。
current_user.posts.first.hide_twitter
=> false
current_user.posts.first.hide_facebook
=> true
当我使用上述delegate
并尝试调用上面的代码行时,出现以下错误:
Post Load (1.4ms) SELECT "posts".* FROM "posts" INNER JOIN "post_users" ON "posts"."id" = "post_users"."post_id" WHERE "post_users"."user_id" = $1 ORDER BY "posts"."id" ASC LIMIT 1 [["user_id", 90]]
NoMethodError: undefined method `hide_twitter' for #<Post:0x007fc27d383f50>
from /Users/ACIDSTEALTH/.gem/ruby/2.3.0/gems/activemodel-4.2.5.1/lib/active_model/attribute_methods.rb:433:in `method_missing'
我意识到我可以像this answer那样做一些非常迂回的事情,但希望能有更优雅/传统的东西。
答案 0 :(得分:0)
如下:
class Post < ActiveRecord::Base
has_many :post_users
has_many :users, through: :post_users
end
class User < ActiveRecord::Base
has_many :post_users
has_many :posts, through: :post_users
end
class PostUser < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
然后:
PostUser.where(post: current_user.posts.first).hide_twitter