1

同じ貨物に属する 3 つの請求書があります。作成された最初の請求書は、常に出荷の主要な請求書です。

Invoice 
id   shipment_id
21   55 # This is the main invoice
88   55
93   55

次のクエリを実行すると

s = Shipment.find(55)
s.invoices[0] # 21
s.invoices[1] # 88
s.invoices[2] # 93

したがって、子要素の順序は ID によって決定されると思います。私は正しいですか?それともそれ以上の何かがありますか?

メソッドの 1 つが常に機能するようにするには、子要素の順序を確認する必要があるためです。

def am_i_the_main_invoice?
  if self.shipment.invoices[0].id == self.id
    true
  else
    false
  end
end
4

4 に答える 4

2

明示的に設定しない限り、順序はランダムです。データベースはおそらく同じ順序で要素を返しますが、何かを変更すると(一見無関係なものであっても)、他の順序になる可能性があります。繰り返しますが、クエリで順序を明示的に設定していない限り、リレーショナル データベースから取得した要素の順序を信頼しないでください。

Shipmentおそらく関係をセットアップしているクラスでは、常にIDによる順序を強制するhas_manyようなものを追加できます。:order => "id ASC"

于 2012-08-22T16:20:05.927 に答える
1

順序付けられたクエリに依存する代わりに、invoicesテーブルにフラグを追加できます。

# in migration
add_column :invoices, :is_primary, :boolean, {null: false, default: false}

# if your rdbms supports partial indexes, you can enforce it
execute 'create unique index uniq_single_primary on invoices (shipment_id) where is_primary = true'

# then query is easy ..
def am_i_the_main_invoice?
  self.is_primary?
end
于 2012-08-22T16:28:40.963 に答える
1

通常、返される順序は、使用している SQL データベースによって異なります。通常は主キーに基づいていますが、Holger Justが言ったように、変更される可能性があるため信頼しないでください。

これは、次の 2 つの方法で回避できます。

  1. 請求書モデルにスコープを追加します。これは、コレクションを調べる前に呼び出すことができます。scope :by_shipment, order("id ASC")
  2. default_scope を追加して、常にその順序で取得されるようにします。default_scope order("id ASC")

お役に立てれば

于 2012-08-22T16:31:31.403 に答える