Различие себя, себя [: item] в виртуальном атрибуте с делегатом - PullRequest
1 голос
/ 24 января 2012

есть кое-что, что немного смущает меня, и я хотел бы получить некоторые разъяснения, пожалуйста, так как это вызывает у меня некоторые проблемы.

У меня есть модель города с делегатом атрибута wood_production, который определяет количество древесины в этом городе. Это как:

has_one :wood_production, :autosave => true
delegate :amount, :to => :wood_production, :prefix => true, :allow_nil => true

    def wood
        wood_production_amount
    end

    def wood= amt
      self[:wood_production_amount] = amt
    end

Обычно я хотел иметь возможность сделать city.wood - = 1000 и сохранить это значение через город, но я сталкивался с множеством проблем, связанных с этим. Похоже, я неправильно устанавливаю свои виртуальные атрибуты.

Итак, я бы хотел спросить, в чем разница между ними:

def wood
    self.wood_production_amount
end

def wood
    wood_production_amount
end

def wood
    self[:wood_production_amount]
end

а что на самом деле нужно использовать для правильной обработки ситуации?

РЕДАКТИРОВАТЬ:

Если я создаю сеттер, как:

def wood= amt
  self.wood_production_amount = amt
end

Я получаю:

1.9.2p290 :003 > c.wood -= 1000
 => 58195.895014789254 
1.9.2p290 :004 > c.save
   (0.1ms)  BEGIN
   (0.3ms)  UPDATE `wood_productions` SET `amount` = 58195.895014789254, `updated_at` = '2012-01-24 02:13:00' WHERE `wood_productions`.`id` = 1
   (2.0ms)  COMMIT
 => true

1.9.2p290 :005 > c.wood
 => 66522.63434300483         ???????

Buf, если сеттер:

def wood= amt
  wood_production_amount = amt
end

1.9.2p290 :004 > c.wood -= 1000
 => 58194.823000923556 
1.9.2p290 :005 > c.save
   (0.1ms)  BEGIN
   (0.2ms)  COMMIT
 => true

1 Ответ

2 голосов
/ 24 января 2012

Отвечая на первую часть, self.wood_production_amount и wood_production_amount функционально идентичны.Единственное отличие состоит в том, что в последнем случае подразумевается «я», являющееся текущим примером модели Сити.Я редко использую self.anything, если только это не требуется.

self[:wood_production_amount] функционально аналогично в большинстве первых.Разница в том, что он позволяет легко перезаписывать методы доступа по умолчанию.read_attribute(:attribute) функционально идентичен self[:attribute].Например, скажем, ваша модель города имеет атрибут состояния, но вы всегда хотите возвращать состояние в верхнем регистре при запросе.Вы можете сделать что-то вроде этого:

class City < ActiveRecord::Base
  def state
    self[:state].try(:upcase)
    # or
    read_attribute(:state).try(:upcase)
  end
end

city = City.new(:state => 'vermont')
city.state # => VERMONT

Итак, чтобы ответить на ваш второй вопрос, это действительно зависит от того, как вы хотите его использовать.Лично я бы пошел с методом делегата, если вам не нужно перезаписать какое-то поведение.Причина, по которой это не сработало, может заключаться в том, что вы также не делегируете метод установки :amount=:

delegate :amount, :amount= :to => :wood_production, 
         :prefix => true, :allow_nil => true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...