2

我是 RoR 的初学者,最近自己使用指南进行了一些编码。我目前被困在一个点上,并且已经做了一些谷歌搜索以找到原因,但没有运气。有人可以帮我吗?

我的场景:

class Enum < ActiveRecord::Base
  establish_connection :common
  attr_accessible :name, :description, :updated_at
  has_many :enumlists
  has_many :enumvalues, :through => :enumlists
  validates :name, presence: true, length: { maximum:20}
  validates :description, length: {maximum: 100}
end

class Enumlist < ActiveRecord::Base
  establish_connection :common
  belongs_to :enums
  belongs_to :enumvalues
  attr_accessible :updated_at
end

class Enumvalue < ActiveRecord::Base
  establish_connection :common
  attr_accessible :category, :description, :updated_at
  has_many :enumlists
  has_many :enums, :through => :enumlists
end

迁移条目是:

class CreateEnums < ActiveRecord::Migration
  def change
    create_table :enums do |t|
        t.string :name, :limit=>20
        t.string :description, :limit=>100
        t.timestamps
    end
    add_index :enums, [:name], :unique => true

    create_table :enumvalues do |t|
      t.string :category, :limit=>50
      t.string :description, :limit=>50
      t.timestamps
    end

    create_table :enumlists do |t|
        t.integer :enum_id
        t.integer :enumvalue_id
        t.timestamps
    end
    add_index :enumlists, [:enum_id, :enumvalue_id], :unique => true
  end
end

现在,我想在控制器中查看所有枚举及其值。从我看到的示例中,我可以执行Enum.find(params[:id]).enumlists,但是我找不到使用链接表获取所有枚举的方法。我显然在这里遗漏了一些简单的东西,但我无法弄清楚它是什么..

谢谢..

更新:我可以使用 @enums = Enum.includes(:enumlists) 并且它确实返回正确的条目,但是我无法更深一层.. 即 @enums = Enum.includes(:enumlists, :enumvalues) 然后使用 @ enums.enumlists.enumvalues 获取所有枚举值的列表。

To help, the data is structured as below:
Enums:
-----------------------------------------------------------------------------------
id           name              description
-----------------------------------------------------------------------------------
1            App1 OS            Operating systems for Application 1
2            App2 OS            Operating systems for Application 2

Enumvalues:
-----------------------------------------------------------------------------------
id           category              description
-----------------------------------------------------------------------------------
1            Operating Systems     AIX
2            Operating Systems     Linux
3            Operating Systems     Windows

Enumlists:
-----------------------------------------------------------------------------------
id           enum_id              enumvalue_id
-----------------------------------------------------------------------------------
1            1                    1
2            1                    2
3            2                    1

What i need in the output is:
enums = [ [1, [Operating Sysetms, AIX, Operating Systems, Linux], 2,[Operating Sysetms, AIX] ]

更新:

以下应该工作。

@enums = Enum.includes({:enumlists => :enumvalues})

请注意,名称 enum_lists 和 enum_values 会更符合 Ruby 的习惯

@AlexBlakemore - 谢谢。您的输入让我相信模型中存在问题,一旦我发现它,您的方法和我之前使用的方法似乎都运行良好..

我想我找到了失败的原因。这是由于类 Enumlist 的定义不正确。应该是

class Enumlist < ActiveRecord::Base
  establish_connection :common
  belongs_to :enum   <-- Renamed to enum instead of enums
  belongs_to :enumvalue <-- Renamed to enumvalue instead of enumvalues
  attr_accessible :updated_at
end

进行上述更改后,我尝试使用以下方式链接表格,并且它们都可以正常工作.. Method1:

@enums = Enum.includes(:enumlists, :enumvalues)
  [1m[36mEnum Load (0.4ms)[0m  [1mSELECT `enums`.* FROM `enums` [0m
  [1m[35mEnumlist Load (0.3ms)[0m  SELECT `enumlists`.* FROM `enumlists` WHERE `enumlists`.`enum_id` IN (1, 2)
  [1m[36mEnumvalue Load (0.3ms)[0m  [1mSELECT `enumvalues`.* FROM `enumvalues` WHERE `enumvalues`.`id` IN (1, 2)[0m
@enums = Enum.includes(:enumlists, :enumvalues)
[#<Enum id: 1, name: "WMB OS", description: "Operating System (WMB)", created_at: "2000-01-01 09:00:00", updated_at: "2000-01-01 09:00:00">, #<Enum id: 2, name: "4690 OS", description: "Operating System (DEC)", created_at: "2008-01-01 09:00:00", updated_at: "2008-01-01 09:00:00">]

方法2:使用@AlexBlakemore 的建议,我也得到了类似的输出。

@enums = Enum.includes({:enumvalues=>:enumlists})
  [1m[36mEnum Load (0.2ms)[0m  [1mSELECT `enums`.* FROM `enums` [0m
  [1m[35mEnumlist Load (0.3ms)[0m  SELECT `enumlists`.* FROM `enumlists` WHERE `enumlists`.`enum_id` IN (1, 2)
[#<Enum id: 1, name: "WMB OS", description: "Operating System (WMB)", created_at: "2000-01-01 09:00:00", updated_at: "2000-01-01 09:00:00">, #<Enum id: 2, name: "4690 OS", description: "Operating System (DEC)", created_at: "2008-01-01 09:00:00", updated_at: "2008-01-01 09:00:00">]
  [1m[36mEnumvalue Load (0.6ms)[0m  [1mSELECT `enumvalues`.* FROM `enumvalues` WHERE `enumvalues`.`id` IN (1, 2)[0m
  [1m[35mEnumlist Load (0.4ms)[0m  SELECT `enumlists`.* FROM `enumlists` WHERE `enumlists`.`enumvalue_id` IN (1, 2)

没有错误,所以很明显,这两种方法都在填充列表。但是当我尝试访问枚举列表/枚举值时,我得到了 NoMethodError。我尝试了各种组合,没有一个有效..

@enums.enumlists
@enums.enumlist
@enums.enumvalues
@enums.enumvalue

不知道这里缺少什么..有什么建议吗?一旦我让它工作,我可以确认上述两种方法中的哪一种返回正确的结果。手指交叉!!

4

2 回答 2

1

下面应该告诉 ActiveRecord 在获取枚举时急切地获取枚举列表和枚举值。

@enums = Enum.includes({:enumlists => :enumvalues})

请注意,名称 enum_lists 和 enum_values 会更符合 Ruby 的习惯

或者你可以试试

@enums = Enum.includes(:enumvalues)

如果您真的只是想拥有一个 has_and_belongs_to_many 关联。(HABTM)

于 2012-08-31T16:21:14.193 回答
0

好的..这是解决问题的方法。

第一个错误是连接表以单数形式链接表名,因此连接被破坏。即表格模型应如下所示。它包含对我在查询中发布的原始模型的 3 处更改。一个。将连接表字段重命名为使用单数形式。湾。正如@Alex 所建议的那样,原始表名已重命名为更具标志性的 ruby​​ ctinteger 将其更改为 t.reference 以使其明确。

class Enum < ActiveRecord::Base
  establish_connection :common
  attr_accessible :name, :description, :updated_at
  has_many :enum_lists
  has_many :enum_values, :through => :enum_lists
  validates :name, presence: true, length: { maximum:20}
  validates :description, length: {maximum: 100}
end

class Enum_list < ActiveRecord::Base
  establish_connection :common
  belongs_to :enum   <-- Renamed to enum instead of enums
  belongs_to :enum_value <-- Renamed to enum_value instead of enum_values
  attr_accessible :updated_at
end

class Enum_value < ActiveRecord::Base
  establish_connection :common
  attr_accessible :category, :description, :updated_at
  has_many :enum_lists
  has_many :enums, :through => :enum_lists
end

第二个问题是我试图在控制器中使用 find(:all) 来获得结果。相反,它可以使用以下方法之一轻松完成

@enums = Enum.includes(:enum_lists, :enum_values) or 
@enums = Enum.includes(:enum_values) or 
@enums = Enum.includes({:enum_lists => :enum_values}), 

记住每次使用产生的查询数量。

最后一个问题是我无法使用@enums.enum_lists 在 ruby​​ 控制台上打印值。这宁愿需要在循环中写入以打印值。因此,我在视图中编写了以下代码以将枚举名称及其对应值打印为:

<% @enums.each do |enum| %>
<h4><%= enum.name %></h4>
<table width="100%">
  <tr class="<%= cycle('odd','even', :name=>"line") %>"><td>Description</td><td><%= enum.description %></td></tr>
  <table>
    <% enum.enum_values.each do |enum_value| %>
      <tr class="<%= cycle('odd','even', :name=>"line") %>"><td><%=  enum_value.category %></td><td><%=  enum_value.description %></td></tr>
    <% end %>
      <tr class="<%= cycle('odd','even', :name=>"line") %>"><td colspan="2"><span class="greyed">Last updated <%= time_ago_in_words(enum.updated_at) %> ago</span></td></tr>
  </table>
</table>

非常感谢@Alex 的投入.. !! 我可以继续我的 RoR 工作!

于 2012-09-01T08:05:10.230 回答