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)を使用でき、正しいエントリが返されますが、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)

エラーはないので、明らかに両方の方法でリストにデータが入力されています。しかし、enumlist / enumvaluesにアクセスしようとすると、NoMethodErrorが発生します。私はさまざまな組み合わせを試しましたが、どれもうまくいきませんでした。

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

ここに何が欠けているのかわからない..何か提案をお願いします?? これが機能するようになったら、上記の2つの方法のどちらが正しい結果を返すかを確認できます。成功を祈っている !!

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

OK..これが問題の解決策です。

最初の間違いは、結合テーブルがテーブル名を単一の形式でリンクしていたため、結合が壊れていたことです。つまり、テーブルモデルは次のようになります。クエリに投稿された元のモデルに対する3つの変更が含まれています。a。単数形を使用するように結合テーブルフィールドの名前を変更しました。b。@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

2番目の問題は、コントローラーで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 に答える