我是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
现在,我想在控制器中查看所有Enums及其值。从我看到的例子中,我可以做 Enum.find(params [:id])。enumlists ,但是我找不到用链接表获取所有枚举的方法。我在这里显然遗漏了一些简单的东西,但我无法弄清楚它是什么......
谢谢..
更新:我可以使用@enums = Enum.includes(:enumlists),它确实会返回正确的条目,但是我无法获得更深的1级...即@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会更加惯用 红宝石
@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
进行上述更改后,我尝试使用以下方法链接表格,这两种方法都完美无缺。 方法一:
@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)
没有错误如此清楚,这两个方法都填充了列表。但是当我尝试访问enumlist / enumvalues时,我得到一个NoMethodError。我尝试了各种组合,没有工作..
@enums.enumlists
@enums.enumlist
@enums.enumvalues
@enums.enumvalue
不确定这里缺少什么..有什么建议吗?一旦我开始工作,我可以确认上述两种方法中的哪一种返回正确的结果。手指交叉!!
答案 0 :(得分:1)
以下内容应该告诉ActiveRecord在获取枚举时急切地获取枚举和枚举。
@enums = Enum.includes({:enumlists => :enumvalues})
注意,名称enum_lists和enum_values将是更惯用的Ruby
或者你可以试试
@enums = Enum.includes(:enumvalues)
如果你真的只是想拥有一个has_and_belongs_to_many关联。 (HABTM)
答案 1 :(得分:0)
好的..这是解决问题的方法。
第一个错误是连接表以单数形式链接表名,因为连接被破坏了。即表格模型应如下所示。它包含对查询中发布的原始模型的3个更改。 一个。重命名连接表字段以使用单数形式。 湾正如@Alex所建议的那样,原始表名已经被重命名为更多的idomatic ruby C。 t.integer被改为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工作!!