has_many: через использование, простой вопрос для начинающих - PullRequest
1 голос
/ 23 сентября 2011

Я пишу простую систему учета для управления затратами. Структура выглядит так:

Invoice  - can have many products
  Product - can have many costs, also can act_as_tree 
      LineItem  - 
    Product
        LineItem
        LineItem
      Product
      LineItem
  Product
      LineItem
  LineItem

Я настроил это как has_many и own_to для трех классов, но думаю, что следующее более уместно (основываясь на чтении Rails 3 Way - любые недостатки - это мое непонимание; просто пытаюсь дать контекст)

Class Invoice < ActiveRecord::Base
    has_many :products
    has_many :line_items, :through => :products
end

 Class Product < ActiveRecord::Base
    belongs_to :invoice
    belongs_to :line_item
 end

class LineItem < ActiveRecord::Base
    has_many :products
    has_many :invoices, :through => :invoices
end

Но у меня нет, это работает правильно.

если я сделаю следующее:

>@i=Invoice.find(1)
>@i.products # this works
>@i.line_items # doesn't work, unidentified method line_items

Я впервые использую has_many: through. Правильно ли это настроено для моей модели данных? Кроме того, возможно ли использовать его в сочетании с acts_as_tree - я бы хотел сказать:

>@i.line_items 

и вернуть все позиции для этого конкретного счета. Возможно ли это?

спасибо за помощь

Ответы [ 3 ]

1 голос
/ 24 сентября 2011

почему вы выбрали эту структуру?в таких случаях я обычно выполняю

Class Invoice < ActiveRecord::Base
  has_many :line_items
  has_many :products, :through => :line_items
end

Class Product < ActiveRecord::Base
  has_many :line_items
  # if you need
  has_many :products, :through => :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :products
  belongs_to :invoice
end

, что полностью удовлетворяет следующим требованиям:

Счет-фактура и Продукт имеют отношение Many2Many. Отношение между Счетом-фактурой и Продуктом является LineItem, который предоставляет дополнительную информацию, такую ​​какцена, сумма, применяемые налоги и т. д. Вы можете создать LineItem, добавив продукт:

invoice = Invoice.create
invoice.products << Product.find_by_name('awesome')
1 голос
/ 23 сентября 2011

Первый вопрос: каково ваше отношение между Product и LineItem: имеет ли 1 товар много позиций или на 1 и одну и ту же позицию ссылаются во многих товарах? Остальная часть этого ответа основана на предположении, что у каждого продукта должно быть несколько позиций.

Я думаю, что ваши модели должны быть определены так:

# No change
Class Invoice < ActiveRecord::Base
  has_many :products
  has_many :line_items, :through => :products
end

# Changed the relation to :line_items
Class Product < ActiveRecord::Base
  belongs_to :invoice
  has_many :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :products
  # The following then does not make sense
  ##has_many :invoices, :through => :invoices
end
0 голосов
/ 24 сентября 2011

Ваш счет должен содержать только позиции! Это может быть древовидная структура, но у вас не должно быть товаров, на которые прямо ссылается ваш счет (что, если цена продукта изменится: это повлияет на существующие счета!)

Итак, чтобы исправить вашу структуру:

invoice
  line_item   # references a product, but has its own fields (price!)
  line_item
    line_item

Каждый line_item должен ссылаться на один продукт, используя belong_to. Это ваша модель соединения между счетами и продуктами:

class Invoice
  has_many :line_items
end

class LineItem
  belongs_to :invoice
  belongs_to :product
  acts_as_tree # (implies has_many :line_items with the parent invoice_id, etc.)
end

class Product
  has_many :line_items
end

Это в основном все, что вам нужно для создания счета. Вы можете думать о древовидной структуре как о не зависящей от отношения Invoice:LineItem:Product. Он может работать как плоский список или улучшаться, чтобы стать деревом.

Если ваши продукты обычно содержат другие продукты, и вам необходимо знать, какие дочерние элементы добавляются в счет-фактуру при добавлении родительского продукта (в виде позиций), вам также необходимо создать свои продукты в виде дерева:

class Product
  has_many :line_items
  acts_as_tree
end

Эта древовидная структура не зависит от древовидной структуры в позициях. Помните: товары могут меняться, и это не должно влиять на существующие позиции в ваших счетах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...