Рельсы "автоматического" определения объема внутри модели - PullRequest
0 голосов
/ 07 мая 2019

В настоящее время я сталкиваюсь со следующей проблемой. У меня есть следующие 2 модели:

  1. PageElement

  2. Страница

Страница has_many :page_elements, и я добавил следующее отношение has_many в модель page_element:

  #PageElement model
  has_many :siblings, ->(pe) { where.not(id: pe.id) }, through: :page, class_name: "PageElement", source: :page_elements

Итак, внутри метода, называемого set_position, я ищу самую высокую позицию братьев и сестер и устанавливаю ее на 1 цифру выше:


  def set_position
    if position.zero? && siblings.present?
      new_position = (siblings.order("position ASC").pluck(:position).last + 1 rescue 0)
      update(position: new_position) if position != new_position
    end
  end

Однако, когда я смотрю на запрос, сгенерированный методом siblings, я вижу, что по какой-то причине он автоматически ограничивается в зависимости от "элемента текущей страницы":

  PageElement Load (0.6ms)  SELECT  "page_elements".* FROM "page_elements" WHERE "page_elements"."page_id" = $1 AND "page_elements"."element_type" = $2 ORDER BY "page_elements"."position" ASC LIMIT $3  [["page_id", 69], ["element_type", 6], ["LIMIT", 1]]

Как вы можете видеть, важной частью здесь является то, что он фильтрует по «текущему типу элемента», который равен 6. Однако я ожидаю не такого поведения, так как хочу получить всех братьев и сестер, без какого-либо вида фильтрации.

Почему рельсы автоматически определяют область на основе текущего элемента? Я также выяснил, что это происходит с другими видами столбцов, такими как строки, если я добавлю к этому элементу title, он также будет фильтровать по этой строке заголовка.

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

  has_many :siblings, ->(pe) { unscoped.where.not(id: pe.id) }, through: :page, class_name: "PageElement", source: :page_elements

Однако я бы хотел понять, почему он изначально ограничен, так что я понимаю, что я не делаю ничего плохого.

UPDATE:

Я обнаружил, что эта «область видимости» происходит только тогда, когда я запускаю эти отношения в методе, вызванном after_commit. При использовании rails console я пытаюсь сделать PageElement.first.siblings, я получаю правильный запрос SQL:

irb(main):002:0> PageElement.last.siblings
  PageElement Load (0.7ms)  SELECT  "page_elements".* FROM "page_elements" ORDER BY "page_elements"."id" DESC LIMIT $1  [["LIMIT", 1]]
  PageElement Load (0.8ms)  SELECT  "page_elements".* FROM "page_elements" INNER JOIN "pages" ON "page_elements"."page_id" = "pages"."id" WHERE "pages"."id" = $1 AND "page_elements"."id" != $2 ORDER BY "page_elements"."position" ASC LIMIT $3  [["id", 79], ["id", 200], ["LIMIT", 11]]

UPDATE2:

После еще нескольких копаний я обнаружил, что проблема в том, что я генерирую эти экземпляры в файле seed, используя where(element_type: 'something').first_or_create. Используя first_or_create, отношения «братьев и сестер» автоматически ограничиваются. Я выяснил причину проблемы, но не причину ее появления.

В настоящее время мы используем page_instance.page_elements.where(some_condition).first_or_create, чтобы мы могли снова и снова запускать файл seed без получения дубликатов.

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