【问题标题】:How to link to items in an enum -can't cast Enumerator error如何链接到枚举中的项目 - 无法投射枚举器错误
【发布时间】:2020-05-15 12:19:33
【问题描述】:

我有一个枚举,我希望有一个链接,该链接将显示该枚举下的所有帖子,但我不断收到“无法投射枚举数”的消息,最好的方法是什么,或者我该如何解决这个错误?

enum status: [:lost, :found]

查看枚举中项目的链接

<li class="nav-item"><%= link_to "Lost", items_path(status: "lost"), class: "nav-link" %></li>
<li class="nav-item"><%= link_to "Found", items_path(status: "found"), class: "nav-link" %></li>

我的控制器看起来像这样

def index
    if params.has_key?(:status)
      @status = Item.statuses.find(params[:status])
      @items = Item.where(status: @status)
    else
      @items = Item.all
    end
  end

我的观点由此开始

<% @items.each do |item| %>
    <%= content_tag :tr, id: dom_id(item), class: dom_class(item) do %>
    ...

【问题讨论】:

  • 能否请您在描述中添加错误?如果不了解错误在哪里,就很难尝试一些解决方案。

标签: ruby-on-rails ruby enums ruby-on-rails-6


【解决方案1】:

什么是最好的方法

我认为最好的方法是使用哈希作为枚举和后缀(或前缀),如下所示:

enum status: { lost: "lost", found: "found" }, _suffix: true

在这种情况下,您需要将status 作为字符串保存在您的items 表中

这样做有什么好处?

它创建范围:Item.lost_statusItem.found_status

现在你可以这样使用它了:

<li class="nav-item"><%= link_to "Lost", items_path(status: "lost"), class: "nav-link" %></li>
<li class="nav-item"><%= link_to "Found", items_path(status: "found"), class: "nav-link" %></li>

在控制器中:

def index
  @items =
    if params[:status].present?
      Item.send("#{params[:status]}_status")
    else
      Item.all
    end
end

【讨论】:

  • Hashenum status: [:lost, :found] 有什么好处,enum status: [:lost, :found] 将通过索引映射到整数值?
  • 你没有绑定到数组索引。您可以在以后添加新值并删除旧值,而不必担心它们的顺序。它更具可扩展性
  • 出色的推理。删除枚举似乎很危险,尽管没有考虑迁移旧值。
  • 我现在试过了,但是当我点击丢失或找到的链接时,我没有得到任何物品
  • @mechnicov 我非常确信我在答案中添加了迁移模式。如果您不同意或发现过程中有任何缺陷,请告诉我
【解决方案2】:

如果你希望保持它的原样,那么你需要适当地访问枚举:

def index
    if params.has_key?(:status)
      @status = Item.statuses[params[:status]]
      @items = Item.where(status: @status)
    else
      @items = Item.all
    end
  end

这将返回枚举表示的整数。但是还有更直接的方法,例如

@items = Item.where(status: params[:status]) # Rails >= 5.0

甚至

@items = Items.public_send(params[:status]) # Rails >= 4.1 (when enum was introduced)

使用通过enum 方法创建的范围。

See Here 了解更多信息。

因为@mechnicov 说服我Hash 模式更好,所以我将如何迁移到这个

  • 把枚举改成Itemenum status: { lost: "lost", found: "found" }

  • 创建新迁移以添加新列 (status2)

def change  
  add_column :items, :status2, :string
end 
  • 创建另一个新迁移以迁移数据
def change 
 Item.reset_column_information
 [:lost,:found].each_with_index do |status,index|
   Item.where(status: index).update_all(status2: status)
 end 
 remove_column :items, :status
 rename_column :items, :status2, :status 
end

【讨论】:

  • 谢谢。这是处理此类事情的最佳方法吗?
  • @albert 老实说 mechnicov 已经让我相信 Hash 解决方案更好,但这不是你可以直接跳进去的东西,你需要改变你的模式(两次)并创建一个迁移模式。所以对于你现在使用的,我会说是的。要移动到哈希模式,您需要创建一个新列(字符串)来保存新值,然后您需要将当前枚举映射到新哈希枚举,删除当前状态列,然后重命名您创建的新列到状态。我会将其添加到我的答案中。
猜你喜欢
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多