Как мне создать массив ассоциаций из заданной строки? - PullRequest
0 голосов
/ 01 апреля 2020

Учитывая, что у меня есть объект AR (object) и строка (s). s основано на ассоциациях объекта. ie. Продукт принадлежит проходу, проход принадлежит отделу, отдел принадлежит магазину

Я хочу получить массив всех этих ассоциаций. Вот что я придумала

object = Product.last
s='aisle.department.shop'

new_array = s.split(',').each_with_object([]).with_index do |(assoc_set, array), index|
  a = assoc_set.split('.')
  a.each_with_index do |assoc, index|
    if index == 0
      array << object.send(assoc)

    elsif index == 1
      array << object.send(a[index - 1]).send(a[index])

    elsif index == 2
      array << object.send(a[index - 2]).send(a[index - 1]).send(a[index])

    elsif index == 3
      array << object.send(a[index - 3]).send(a[index - 2]).send(a[index - 1]).send(a[index])
    end
  end
end

Выводит именно то, что я хочу:

[
  #<Aisle:0x00007fa001d6f800 ...>,
  #<Department:0x00007fa001d44b00 ...>,
  #<Shop:0x00007fa020f4bc68 ...>,
]

За исключением кода, который не является динамическим c. Как вы можете видеть, он поднимается только на 3 уровня. Как я могу рефакторинг это?

1 Ответ

2 голосов
/ 01 апреля 2020

Это должно работать так, как вы хотели

object = Product.last
relations_chain='aisle.department.shop'

relations_chain.split('.').each_with_object([]).with_index do |(relation_name, array), index|
  prev_object = index.zero? ? object : array[index - 1]
  array << prev_object.send(relation_name)
end

Вы можете делегировать отношения и вызывать все на Product модели.

class Department < ApplicationRecord
  delegate :shop, to: :department, allow_nil: true
end

class Product < ApplicationRecord
  delegate :department, to: :aisle, allow_nil: true
  delegate :shop, to: :aisle, allow_nil: true
end

relations_chain.split('.').map { |relation_name| object.send(relation_name) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...