【问题标题】:How to Show Name Instead of Id in Rails如何在 Rails 中显示名称而不是 ID
【发布时间】:2015-09-30 18:51:39
【问题描述】:

这个问题把我彻底难住了。我还是 RoR 和学习的新手。

我有两张桌子:Countertops 和 Countmaterial。用户将为他们的台面选择所有功能,包括材料类型。材料的选项列在 Countmaterial 表中,并且是从集合中选择的。

我的问题是,一旦做出选择并创建了 Countertop,如何在 Countertops 的索引页面上显示材料类型的名称,而不是 countertype,这是为匹配 Countmaterial 表中的名称而生成的整数?

例如,我希望索引显示“Granite”而不是“1”。 “Granite”列在 Countmaterial 表中,当用户选择“Granite”时,它会在 Countertype 列中将 Countertop 表填充为“1”。大理石是一个“2”等等......

这是我的架构:

create_table "countertops", force: :cascade do |t|
 t.string   "size"
 t.string   "color"
 t.datetime "created_at",  null: false
 t.datetime "updated_at",  null: false
 t.string   "ZipCode"
 t.string   "countertype"
end

create_table "countmaterials", force: :cascade do |t|
 t.string   "name"
 t.datetime "created_at",    null: false
 t.datetime "updated_at",    null: false
 t.integer  "countertop_id"
end

我的台面控制器用于索引:

def index
 @countertops = Countertop.all
 @countertops = Countertop.includes(:countmaterial).all
end

我的索引代码:

<% @countertops.each do |countertop| %>
  <tr>
    <td><%= countertop.ZipCode %></td>
    <td><%= countertop.countmaterial.name %></td>

协会:

class Countertop < ActiveRecord::Base
  has_one :countmaterial
end

class Countmaterial < ActiveRecord::Base
  belongs_to :countertop
end

大家怎么看?

【问题讨论】:

  • &lt;td&gt;&lt;%= countertop.countmaterial.name %&gt;&lt;/td&gt; 不是给你的名字吗?
  • 不。我收到“nil:NilClass 的未定义方法‘名称’”作为错误。
  • 好的,让我们做一些快速调试。请将您的索引更改为 它应该给出一些奇怪的斑点数据,请发布。
  • 其实试试这个 我想你可能有一些数据库中没有计数材料的台面实体
  • inspect.to 行的错误是“范围值错误”

标签: mysql ruby-on-rails associations


【解决方案1】:

您可能会对您的具体型号名称感到困惑;命名模型和控制器时 - 保持超级简单。一个字……

#app/models/counter.rb
class Counter < ActiveRecord::Base
   #columns id | type_id | material_id | size_id | color_id | zip_code| created_at | updated_at
   belongs_to :type
   belongs_to :material
   belongs_to :size
   belongs_to :color
   delegate :name, to: :size, prefix: true
end

#app/models/option.rb
class Option < ActiveRecord::Base
   #columns id | Type | name | created_at | updated_at
   has_many :counters
end

#app/models/size.rb
class Size < Option
end

#app/models/type.rb
class Type < Option
end

#app/models/color.rb
class Color < Option
end

#app/models/material.rb
class Material / Option
end

这将使您能够执行以下操作:

#config/routes.rb
resources :counters

#app/controllers/counters_controller.rb
class CountersController < ApplicationController
   def index
      @counters = Counter.all
   end
end

#app/views/counters/index.html.erb
<% @counters.each do |counter| %>
   <%= counter.size_name %>
<% end %>

为了让您了解其工作原理,您需要知道 Rails 和 Ruby 是面向对象的。这可能意义不大,但在使用它们开发应用程序时非常重要。

Object orientated programming 是一种将 object 置于代码中心的模式。当您了解它的工作原理时,没有什么会永远是相同的......

在“传统”编程中,您使用的是用户流。这被称为event driven programming,虽然适用于标准应用程序,但它不适合 Ruby/Rails 环境。

Web 应用程序能够处理更多的数据/功能,因此将所有内容都视为对象非常有意义。

因此,无论何时处理 Ruby,您都必须从您尝试 CRUD (Create Read Update Destroy) 的对象的角度考虑一切

这就是为什么你的CounterTop 模型有点粗略——你试图调用的对象是什么?

一旦您看到 object 位于 Rails 工作方式的核心,您就可以围绕它构建一切,如上所述。

【讨论】:

  • 感谢您花时间解释这一点,Rich。虽然,读完之后,我很困惑。在这个应用程序中,我试图让 Countertop 成为应用程序运行的中心对象。因此,材料、尺寸、材料类型等都描述了核心台面。我添加了 Countertype 和 CountMaterial,因为我希望最终扩展应用程序以包含其他具有相似属性的产品。因此,如果我有五种不同的产品都有自己可能的颜色,那么将模型命名为“颜色”并不是一个聪明的主意。
  • 另外,您将 Counters 设置为属于属性,而不是相反,您可以输入 Options,然后输入自己的模型?看起来比使用反色、橱柜色、反色、反材料等要简单得多。
猜你喜欢
相关资源
最近更新 更多
热门标签