У меня слишком многослойная структура базы данных, однако мне она, похоже, нужна.То есть каждый из посетителей нашего веб-сайта может иметь одну учетную запись с поддержкой нескольких пользователей (например, идентификаторов).Теперь они могут создавать заявки, сгруппированные по разделам заявки, и у нас есть менеджер билетов (оператор) для обработки входящих заявок.Не каждый менеджер билетов может видеть каждый билет, но только те, для которых этот менеджер является участником данного раздела заявки.
Теперь я полностью справляюсь с запросами через необработанные операторы SQL, но мне не удалось выразить словами эти два специальныхзапрашивает путь Rails.
Вот (абстрактная) модель:
# account system
class Account < ActiveRecord::Base
has_many :users
has_many :tickets, :through => :users
has_many :managing_ticket_sections, ... # TicketSection-collection this account (any of its users) is operate for
has_many :managing_tickets, ... # Ticket-collection this account (any of its users) may operate on
end
class User < ActiveRecord::Base
belongs_to :account
has_many :tickets
has_many :managing_ticket_sections, ... # TicketSection-collection this user is operate for
has_many :managing_tickets, ... # Ticket-collection this user may operate on
end
# ticket system
class Ticket < ActiveRecord::Base
belongs_to :author, :class_name => "User"
belongs_to :assignee, :class_name => "User"
belongs_to :section, :class_name => "TicketSection"
end
class TicketSection < ActiveRecord::Base
has_many :tickets
has_many :operators
end
class TicketSectionManager < ActiveRecord::Base
belongs_to :manager, :class_name => "User"
belongs_to :section
end
Мне известны базовые has_many :through
-конструкты, однако здесь я обращаюсь к более чем трем таблицамчтобы получить билеты.
Что-то, на самом деле работает в модели пользователя:
class User < ActiveRecord::Base
has_many :managing_relations, :class_name => "TicketSectionManager" # XXX some kind of helper, for the two below
has_many :managing_sections, :class_name => "TicketSection", :through => :managing_relations, :source => :section
has_many :managing_tickets, :class_name => "Ticket", :through => :managing_relations, :source => :section
end
Здесь я использую вспомогательное отношение (managing_relations
), которое абсолютно никогда не используется, кромедвумя отношениями has_many ниже.Я не смог описать отношение User.managing_sections или User.managing_tickets без этого помощника, где мне нужен совет.
Во-вторых, клиент должен посмотреть все билеты, которые онможет управлять любым пользователем (представьте себе личность), в который он вошел, так что мне нужен способ собрать все билеты (/ разделы), которыми может управлять эта учетная запись (идентифицированная как членсоответствующего TicketSection)
Здесь я даже не смог выразить это отношение рубиновым способом, и мне пришлось обходить его следующим образом:
class Account
def managing_tickets
Ticket.find_by_sql("SELECT t.* FROM tickets AS t
INNER JOIN ticket_section_managers AS m ON m.section_id = t.section_id
INNER JOIN users AS u ON u.id = m.user_id
WHERE u.account_id = #{id}")
end
end
Буду признателен за любыедобрые советы и большое спасибо заранее, Кристиан Парпарт.