关于rails多态

时间:2017-04-10 07:36:21

标签: ruby-on-rails activerecord

我有三个型号,文章,用户,批准。这是审批表

def change
  create_table :approvals do |t|
    t.references :user, foreign_key: true
    t.references :approvable, polymorphic: true

    t.timestamps
  end
end

这是三个模型

class User < ApplicationRecord
  has_many :approvals    
  has_many :articles, dependent: :destroy
end 

class Article < ApplicationRecord
  belongs_to :user
  has_many :approvals, as: :approvable
end


class Approval < ApplicationRecord
  belongs_to :user
  belongs_to :approvable, polymorphic: true
end

现在我想在文章显示页面中显示一个批准图像,如果current_user已经批准了该文章,那就不一致了,我认为有一种非常方式可以做到这一点,但我只能来用一种愚蠢的方式来 这样做,如:

<% @article.approvals.each do |approval| %>
   <% if approval.user_id == current_user.id %>
     # show has approvaled image
   <% end %>
<% end %>

我认为这可能效率低下,请告诉我一个更好的解决方案,谢谢! :)

也许我没有表达得很好,我的意思是批准是赞美还是喜欢?

2 个答案:

答案 0 :(得分:0)

您可以先检查属于current_user和文章的批准。

所以在controller方法使用中(考虑到你一次只有一篇文章),

@current_user_approvals = Approval.where(user_id: current_user.id, article_id: @article.id)

然后使用@current_user_approvals in view as,

<% @current_user_approvals.each do |approval| %>
   # show has approval image
<% end %>

答案 1 :(得分:0)

在这种情况下不应使用多态。你可以使用has_many:through来获得批准。阅读文档here

迁移将是:

class CreateApprovals < ActiveRecord::Migration[5.0]
  def change
    create_table :approvals do |t|
      t.belongs_to :user
      t.belongs_to :article
    end
  end
end

模型就像:

class User < ApplicationRecord
  has_many :articles, dependent: :destroy

  has_many :approvals
  has_many :approved_articles, through: :approvals, source: :article
end

class Article < ApplicationRecord
  belongs_to :user

  has_many :approvals
  has_many :approved_users, through: :approvals, source: :user
end

class Approval < ApplicationRecord
  belongs_to :user
  belongs_to :article
end

现在我们可以做一些技巧(在rails控制台中):

# create a user
user = User.create(name: 'user')
# create an article
article = user.articles.create(name: 'article')

# check whether article is approved
user.approved_articles.include?(article) # => false
# approve the article
user.approved_articles << article
# check check whether article is approved again
user.approved_articles.include?(article) # => true

已编辑的版本,因为我们确实希望在批准时使用多态。关键是使用source_type来指定多态类型(在这种情况下它是'Article')

class User < ApplicationRecord
  has_many :articles, dependent: :destroy

  has_many :approvals
  has_many :approved_articles, through: :approvals, source: :approvable, source_type: 'Article'
end

class Article < ApplicationRecord
  belongs_to :user

  has_many :approvals, as: :approvable
  has_many :approved_users, through: :approvals, source: :user
end

class Approval < ApplicationRecord
  belongs_to :user
  belongs_to :approvable, polymorphic: true
end

在控制台上面进行测试仍然有效。