acts_as_tree и распространение значения через подзаголовки к элементам - PullRequest
3 голосов
/ 16 февраля 2012

У меня немного сложная модель, и я хочу получить полную функциональность с моим ограниченным пониманием рельсов.

У меня есть раздел, заголовок (который использует act_as_tree) и элемент.

Я использую json для ввода наборов данных. Это сработало очень хорошо. Я хотел бы иметь возможность вводить атрибуты для целых наборов данных, таких как 'is_shippable'. Я хотел бы иметь возможность указать в любом месте дерева значение is_shippable и установить значение true. Кроме того, я хотел бы иметь возможность переопределить на уровне заголовка или элемента, чтобы установить его в false.

Я решил, что имеет смысл иметь is_shippable в качестве атрибута для раздела, заголовка и элемента и попытаться использовать обратный вызов before_create, чтобы определить, должен ли он быть is_shippable.

Например:

section
  header -acts_as_tree
    item - is_shippable

образец JSON:

{
 "name":"sample section",
 "is_shippable": true,
 "headers_attributes":[
   {
    "name":"sample_section"
    "items_attributes":[{
      "name":"sample item",
      "is_shippable":false,
           }
    ]       
   }
 ]

}

в header.rb

before_save :default_values
private 
def default_values
  self.is_shippable ||=self.section.is_shippable
  # need to be able to set header to is_shippable=false if specified explicitly at that level    
end

в item.rb

before_save :default_values


private 
def default_values
  # if not set, default to 0
  self.is_shippable ||= 0
  self.is_shippable=1 if self.header.is_shippable==true
  # need to be able to set item to is_shippable=false if specified explicitly at that level
end

Есть ли лучший способ сделать это, чем я? Как мне выполнить, если в инструкциях проверяется, установлено ли для is_shippable значение false, если в иерархии установлено значение true выше?

РЕДАКТИРОВАТЬ - также есть другие функции, которые is_shippable, такие как is_fragile, is_custom_size и т.д ...

Ответы [ 2 ]

1 голос
/ 27 февраля 2012

Я бы более склонен использовать before_filter в контроллере для изменения параметров вложенного элемента.

что-то вроде:

before_filter :set_is_shippable, :only => [:update, :create]

def set_is_shippable
  is_shippable = params[:section][:is_shippable]
  params[:section][:items_attributes].each_with_index do |item, index|
    unless item[:is_shippable]
      params[:section][:items_attributes][index][:is_shippable] = is_shippable
    end
  end
end
0 голосов
/ 01 марта 2012

Я настоятельно рекомендую драгоценный камень ancestry.Он имеет гораздо больше методов обхода дерева, а также оптимизирует количество запросов к базе данных.

Если я правильно понимаю вашу дилемму, ancestry позволит вам сделать что-то вроде:

@section.descendants.all?(&:is_shippable)

В любом случае, родословная гораздо более выразительна и, безусловно, даст вам большую гибкость.Вики-сайт github, указанный ниже для драгоценного камня, является лучшим, что я когда-либо видел.Очень хорошо организованный, возможно, прочитав его, вы получите еще несколько идей.

https://github.com/stefankroes/ancestry

http://railscasts.com/episodes/262-trees-with-ancestry

...