简体   繁体   English

有没有比使用STI或多态关联更简单的方法?

[英]Is there a simpler way than using STI or polymorphic associations?

I have been reading a lot on the difference between STI and polymorphic associations and decided to use STI: 我已经阅读了很多有关STI和多态关联之间的区别的内容,并决定使用STI:

user.rb
Class User < ActiveRecord::Base
   has_many :articles
end

article.rb
Class Article < ActiveRecord::Base
   belongs_to :users
end

sport.rb
Class Sport < Article
end

politic.rb
Class Politic < Article
end

food.rb
Class Food < Article
end

create_table "articles", force: :cascade do |t|
t.string   "title"
t.string   "artwork"
t.integer  "user_id"
t.datetime "created_at",                 null: false
t.datetime "updated_at",                 null: false
t.boolean  "approved",   default: false
t.string   "type"

However, upon further reading , this becomes even more complicated. 但是,进一步阅读后 ,情况变得更加复杂。 All I am really looking to do is to find some way to sort my articles by type. 我真正想做的就是找到某种方式来按类型对我的文章进行排序。 For example, is it possible that I simply have a string column tag and specify that tag must be either politics, sports, or food ? 例如,是否可以仅使用一个string column tag并指定该标签必须是politics, sports, or food

In this case, use an enum : 在这种情况下,请使用一个enum

#app/models/article.rb
class Article < ActiveRecord::Base
  enum article_type: [:sport, :politic, :food] #-> "article_type" (int) column required
end 

The only drawback to this would be that you can only assign one enum value to your model; 唯一的缺点是您只能为模型分配一个枚举值。 from the use case you've outlined, it seems that's what you need. 从您概述的用例看来,这就是您所需要的。


The enum will allow you to use the following: enum将允许您使用以下内容:

@article = Article.find params[:id]

@article.sport?    #-> true
@article.politic?  #-> false
@article.food?     #-> false

@article.profile_type #-> "sport"

You also get a set of class methods to identify the various objects you need from the db: 您还将获得一组class methods来从db中标识所需的各种对象:

@sports_articles = Article.sport #-> collection of "sport" articles

To create an @article through a form, you'll need collection_select : 要通过表单创建@article ,您需要collection_select

#app/views/articles/new.html.erb
<%= form_for @article do |f| %>
   <%= f.collection_select :profile_type, Article.profile_types, :first, :first %>
   <%= f.submit %>
<% end %>

Update 更新资料

Pagination occurs on data received from the db. 分页发生在从数据库接收的数据上。

Thus, if you wanted to "include" data in the pagination, you'd just have to make sure you're pulling it from the db. 因此,如果要在分页中“包含”数据,则只需确保要从数据库中提取数据即可。 To do this, you'd need to include as many article_types as you want: 为此,您需要包括article_types

#app/models/article.rb
class Article < ActiveRecord::Base
   scope :by_type, (types) -> { where(article_type: Array.new(types)) }
end

This will allow you to use the following: 这将允许您使用以下内容:

@articles = Article.by_type(:sport, :politic).paginate(page: params [:page], per_page: 12)

As per the docs : 根据文档

Conversation.where(status: [:active, :archived])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM