Rails ActiveRecord: автоматически псевдоним / добавочный суффикс? - PullRequest
1 голос
/ 04 февраля 2009

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

some_field_c
some_other_field_c
a_third_field_c

Я бы очень хотел создать подкласс Rails ActiveRecord, который автоматически присваивает этим атрибутам их имена без знака подчеркивания и "c". Тем не менее, когда я пытался:

attributes.each_key do | key |
  name = key
  alias_attribute key.to_sym, key[0, (key.length -2)].to_sym if key =~ /_c$/
end

в моем определении класса я получил ошибку «неопределенная локальная переменная или метод« атрибуты »». Я также попытался переписать эти методы:

method_missing
respond_to?

но я тоже получал ошибки с этим маршрутом.

Итак, мой вопрос (на самом деле вопросы):

  1. Возможно ли то, что я пытаюсь сделать?
  2. Если так, как лучше всего это сделать (отсутствует метод итеративного псевдонима или перезаписи)?
  3. Если это не так уж и сложно, очень краткий пример кода того, как сделать №2, был бы великолепен.

Заранее спасибо за любые ответы, которые получает это сообщение.

Ответы [ 3 ]

2 голосов
/ 04 февраля 2009

Ваша проблема, вероятно, в том, что attributes является методом экземпляра, и вы делаете это в контексте класса. Метод класса, который ближе всего к тому, что вы хотите, это column_names.

1 голос
/ 04 февраля 2009

Хм ... Я приготовил это маленькое решение, которое, как мне показалось, получилось довольно элегантно ...

Не уверен, будет ли это работать, но я добавил псевдоним method_missing, чтобы разрешить active_record выполнять свои действия:

module ShittyDatabaseMethods
  alias :old_method_missing :method_missing

  def method_missing(method)
    if methods.include?("#{method}_c")
      send("#{method}_c".to_sym)
    else
      old_method_missing(method)
    end
  end

end

class Test
  attr_accessor :test_c
  include ShittyDatabaseMethods
end

Возможно, вам не удастся назвать ваш модуль "ShittyDatabaseMethods", но вы поймете идею;) Как только вы определите этот модуль и поместите его в lib, вам просто нужно включить этот модуль и все готово: D

Хотелось бы услышать, если это сработает для вас:)

1 голос
/ 04 февраля 2009

вы можете сделать что-то вроде:

methods.each do |method|
  if method.ends_with("_c") then
    self.send(:defind_method,method.slice(0,-2)){self.send(method)}
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...