Как я могу заставить блок state_machine использовать метод доступа по умолчанию вместо моего пользовательского метода доступа?

Я реализую гем state_machine от pluginaweek. Я сузил код только до этого, чтобы мне было легче понять проблему. Предположим, у меня пока только один статус:

class Event < ActiveRecord::Base
  state_machine :status, :initial => :active_offer do
  end

  def status
    'Active Offer'
  end
end

Ошибка, которую я получаю при создании новых объектов Event либо с помощью заполнения, либо через браузер: {:status=>["is invalid"]}.

План состоит в том, чтобы включить условие для всех различных статусов и вернуть пользовательскую строку в представление. Представления всего проекта в настоящее время используют синтаксис .status, поэтому я пытаюсь плавно установить его. Я начал это решение на основе чтения документов API:

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Overwriting+default+accessors

Это моя основная цель:

def status
  if read_attribute(:status) == 'active_offer' && self.start_date > Time.now
    'Active Offer'
  elsif read_attribute(:status) == 'active_offer' && self.start_date < Time.now
    'Expired'
  else read_attribute(:status) == 'cancelled'
    'Cancelled'
  end
end

Что я могу сделать, чтобы блок state_machine использовал обычный метод доступа, чтобы получить значение базы данных?

РЕШЕНИЕ "СЕРЕБРЯНАЯ ПУЛЯ":

Моя главная проблема заключалась в переопределении аксессора status. Когда код state_machine выполнялся, он считывал текущий статус с помощью переопределения моего метода доступа и, следовательно, возвращал пользовательскую строку, которая была недопустимым статусом. Мне пришлось заставить state_machine использовать :state. Первоначально я этого не делал, потому что у меня уже был атрибут :state для провинций и тому подобного, поэтому я перенес его в :address_state.


person RudyOnRails    schedule 13.02.2013    source источник


Ответы (1)


Уверен, вам просто нужно изменить имя определения:

class Event < ActiveRecord::Base
  state_machine :status, :initial => :active_offer do
  end

  def active_offer
    'Active Offer'
  end
end

ИЗМЕНИТЬ:

Если я правильно вас понял, что я не уверен, это сработает:

state_machine :status, initial: :active_offer do
  event :expire do
    transition all => :expired
  end
  event :cancel do
    transition all => :cancelled
  end
end

Затем вы можете выполнять свои операторы if... и т. д. в контроллере или что-то в этом роде и передавать их с помощью чего-то вроде @event.expire или if @event.expired. Если вы хотите, чтобы это было автоматизировано, вам понадобится что-то вроде когда угодно.

person okay56k    schedule 13.02.2013
comment
Извините, я не включил достаточно информации в первый раз, чтобы помочь людям понять, в чем заключалась моя главная цель. Пожалуйста, просмотрите мои правки, если можете, возможно, это изменит ваше решение, чтобы я мог сохранить его как «статус». Спасибо. - person RudyOnRails; 14.02.2013
comment
Итак, вы хотите, чтобы это происходило автоматически, или вы запускаете эти методы с помощью кнопок или чего-то подобного? - person okay56k; 14.02.2013
comment
Кнопки не срабатывают. На данный момент, скажем, у меня есть указатель событий. Один из столбцов в таблице событий в представлении индекса — это статус. Поэтому я хотел бы сохранить этот код таким же и просто отредактировать то, что он получает от модели. - person RudyOnRails; 14.02.2013
comment
спасибо за усилия до сих пор. Чтобы вы оказались на той же странице, что и я (!), скажем, в моем представлении шоу, я хочу, чтобы что-то вроде @event.status возвращало активное предложение или любую другую строку на основе условий внутри аксессора. - person RudyOnRails; 14.02.2013
comment
Я думаю, что строка будет чем-то вроде active_offer на основе символа. Мне нужно что-то вроде активного предложения и другие пользовательские строки для всех других состояний/статусов. Еще раз спасибо за продолжение. - person RudyOnRails; 14.02.2013
comment
Ах! Слишком легко. Вы хотите @event.status.titlecase. Бум. - person okay56k; 14.02.2013