You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails:ActiveRecord中Boolean与Enum选型咨询(ArtworkViews模型)

Boolean vs. Enum for liked Field in Rails + PostgreSQL

Great question—let’s break this down based on your art-Tinder app’s needs, especially looking ahead to your upcoming recommendation logic.

Boolean Type: Simple, Efficient, and Straightforward

If your use case stays strictly binary (only "like" or "dislike"), a boolean liked field is a rock-solid choice. Here’s why:

  • Query simplicity: PostgreSQL has first-class support for booleans, so your ActiveRecord queries will be clean and intuitive:
    # Count a user's liked artworks
    current_user.artwork_views.where(liked: true).count
    # Find artworks disliked by a specific user
    Artwork.joins(:artwork_views).where(artwork_views: { user_id: current_user.id, liked: false })
    
  • Performance: Booleans take up minimal storage (just 1 byte in PG) and index extremely well—critical when you start running aggregate queries to build user preference profiles for recommendations.
  • Low overhead: No extra model configuration needed; just define the boolean column in your migration and you’re ready to go.

The main downside? It’s inflexible if you ever want to add more states (like "skipped," "saved for later," or "neutral"). Expanding would require a migration to either change the field type or add a new column, which can be a hassle in production.

Enum Type: Semantic, Extensible, and Intent-Clear

If there’s even a remote chance you’ll expand beyond "like/dislike" down the line, an enum is the smarter bet. Here’s how it works in Rails:
First, use an integer column (more flexible than native PG enums in Rails) and configure the enum in your model:

class ArtworkView < ApplicationRecord
  enum reaction: { liked: 0, disliked: 1 }
end

Then, your queries become even more self-documenting:

# Count liked artworks (no more guessing what `true` means)
current_user.artwork_views.liked.count
# Fetch all disliked records for a user
ArtworkView.disliked.where(user_id: current_user.id)
  • Semantic clarity: Anyone reading your code immediately understands what liked or disliked refers to—no comments required.
  • Easy expansion: Want to add a "skipped" state later? Just update the enum:
    enum reaction: { liked: 0, disliked: 1, skipped: 2 }
    
    No database migration needed (since you’re using an integer-backed enum), which is a huge win for production flexibility.
  • Consistency: Enums enforce valid states at the model level, so you can’t accidentally save a random boolean value or invalid integer that doesn’t map to a reaction.

The only minor tradeoff is a tiny bit of upfront configuration, but that’s negligible compared to the long-term maintainability.

Recommendation Logic Considerations

For your upcoming recommendation system, both types work well, but enums might give you an edge if you ever need to track more nuanced user behavior. For example, if you later want to exclude skipped artworks from recommendations, or weight likes/dislikes differently, enums make it easier to write conditional logic without relying on ambiguous boolean values.

In PostgreSQL, both boolean and integer columns perform similarly for aggregate queries (counts, averages, joins) that you’ll use to build user preference profiles. Performance won’t be a deciding factor here.

Final Recommendation

  • Go with boolean if you’re 100% sure you’ll never need more than "like" and "dislike"—it’s simple, fast, and requires no extra setup.
  • Go with enum if there’s any possibility of expanding states later, or if you want your code to be as readable and maintainable as possible.

Either way, Heroku’s PostgreSQL environment supports both types seamlessly, so you won’t run into deployment issues.

内容的提问来源于stack exchange,提问作者Mike N.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:07:50