установка атрибута activerecord на основе виртуальных атрибутов - PullRequest
3 голосов
/ 10 февраля 2011

у меня есть атрибут с именем dimensions, который я хочу установить на основе моих атрибутов width, height и depth.

например, я хочу сделать ShippingProfile.find(1).width = 4,и сохранить его в размерах как {: width => 4,: height => 0,: deep => 0} `

возможно ли это?

class ShippingProfile < ActiveRecord::Base
  after_initialize :set_default_dimensions

  serialize :dimensions, Hash

  attr_accessor :width, :height, :depth
  attr_accessible :width, :height, :depth, :dimensions

  private

    def set_default_dimensions
      self.dimensions ||= {:width => 0, :height => 0, :depth => 0}
    end  
end

Ответы [ 3 ]

7 голосов
/ 10 февраля 2011

Очень, все, что вам нужно сделать, это использовать обратный вызов для установки значения self.dimensions:

class ShippingProfile < ActiveRecord::Base
  after_initialize :set_default_dimensions
  after_validation :set_dimensions

  serialize :dimensions, Hash

  attr_accessor :width, :height, :depth
  attr_accessible :width, :height, :depth, :dimensions

  private

  def set_default_dimensions
    self.dimensions ||= {:width => 0, :height => 0, :depth => 0}
  end

  def set_dimensions
    self.dimensions = { 
      :width  => self.width || self.dimensions[:width],
      :height => self.height || self.dimensions[:height],
      :depth  => self.depth || self.dimensions[:depth],
    }
  end
end

Вам нужно использовать self.foo || self.dimensions[:foo], чтобы гарантировать, что вы уже сохраните любые существующие значенияустановить в хэш.Зачем?Ваши атрибуты измерения (я предполагаю) не сохраняются в базе данных - вы используете attr_accessor, а не настраиваете их в качестве полей в вашей таблице.

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

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

class ShippingProfile < ActiveRecord::Base
  def dimensions
    { :width => self.width, :height => self.height, :depth => self.depth }
  end
end

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

0 голосов
/ 10 февраля 2011

Вы можете использовать класс в сериализации, поэтому

class ShippingProfile < ActiveRecord::Base
  serialize :dimensions, Dimensions
end

class Dimensions
  attr_accessor :width, :height,:depth

  def initialize
    @width = 0
    @height = 0
    @depth = 0
  end

  def volume
    width * height * depth
  end
end

Теперь вы можете сделать ShippingProfile.dimensions.width = 1 и позже ShippingProfile.dimension.volume и т.д ..

Модельбудет более богатым представлением, чем хэш

0 голосов
/ 10 февраля 2011
ShippingProfile.find(1).dimensions[:width] = 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...