簡體   English   中英

has_many通過rails的所有記錄

[英]all records of has_many through rails

我是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)並返回正確的條目,但是我不能再深入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會更慣用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

進行上述更改之后,我嘗試使用以下方式鏈接表,並且它們都可以正常工作。方法1:

@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

不知道這里缺少什么。 一旦我使它起作用,我就可以確認上述兩種方法中的哪一種返回正確的結果。 手指交叉!

下面的內容應該告訴ActiveRecord在獲取枚舉時急切地獲取枚舉和枚舉。

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

注意,名稱enum_lists和enum_values會更慣用Ruby

或者你可以嘗試

@enums = Enum.includes(:enumvalues)

如果您真的只是想擁有has_and_belongs_to_many關聯。 (HABTM)

好的,這是解決問題的方法。

第一個錯誤是聯接表以單數形式鏈接表名,因此聯接被破壞了。 即表模型應如下所示。 它包含對查詢中發布的原始模型的3個更改。 一種。 重命名聯接表字段以使用單數形式。 正如@Alex所建議的那樣,原始表名已重命名為更多idomatic 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上的工作!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM