Как принудить тип атрибута ActiveRecord, возвращенного: выбрать фразу на объединяемой таблице?

Испытывание затруднений из-за AR 2.3.5, например:

users = User.all( :select => "u.id, c.user_id", :from => "users u, connections c",
       :conditions => ... )

Возвраты, например:

=> [#<User id: 1000>]
>> users.first.attributes
=> {"id"=>1000, "user_id"=>"1000"}

Обратите внимание, что AR возвращается id из модели, искавшей как числовой, но выбранный user_id из модели, к которой присоединяются, как a String, хотя оба int(11) в схеме базы данных.

Как я мог лучше сформировать этот тип запроса для выбора столбцов таблиц, поддерживающих многоуровневые модели и получающих их естественный тип, а не String ? Кажется, что AR плывет на плоскодонке на этом куда-нибудь. Как я мог принудить возвращенные типы во время загрузки AR и не иметь для прикрепления .to_i (и т.д.). на каждый апостериорный доступ?

5
задан tribalvibes 22 April 2010 в 21:23
поделиться

3 ответа

Почему вы используете: from => "users "внутри User.method? Следующее будет выполнять внутреннее соединение (что вы в любом случае делаете)

users = User.all(:include => :connections, :select => "users.id, connections.user_id", :conditions => {...})

Это будет очень сложный запрос для базы данных. Однако более быстрый запрос будет с внешним соединением.

Это также вернет ключи как INT, а не STRING

Гораздо более быстрая альтернатива была

Connection.all(:include => :user, :conditions => {...}).collect {|e| [e.user_id, e.id] }

Это дает вам массив массивов с идентификаторами. Если вы собираетесь выбрать только столбцы «id, user_id», то это не обязательно должно быть как объект AR. Массив может быть быстрее.

Надеюсь, я не упустил здесь какой-то момент. Предложите мне, если я.

1
ответ дан 15 December 2019 в 06:20
поделиться

Это, к сожалению, не произойдет очень легко. Все данные из соединения с БД поступают в rails в виде строк, преобразование типов происходит в каждом из методов динамических атрибутов, которые rails создает во время выполнения. Он знает, какие атрибуты преобразовать в какой тип по метаданным типа столбца таблицы, которые он извлекает при запуске приложения. Каждая модель имеет только метаданные столбца для своих собственных столбцов, поэтому собственные столбцы имеют правильный тип. Нет простого способа автоматического преобразования в правильные типы.

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

Примерно так:

users = User.all(:select => "cl, comments.c2", ...)
users = convert_columns(users, 'c2' => :integer, 'other_column' => :date)

def convert_columns(records, columns = {})
  records.each do |rec|
    columns.each do |col, type|
      rec[col] = case type
         when :int then rec[col].to_i
         when :date then ........
         ....
      end
    end
  end
end
2
ответ дан 15 December 2019 в 06:20
поделиться

Если вам нужно быстрое решение - попробуйте использовать обратный вызов after_find и задайте там правильные типы атрибутов:

class User < ActiveRecord::Base

  after_find :preset_types


  private
  def preset_types user
    user.user_id = user.user_id.to_i
  end

end
0
ответ дан 15 December 2019 в 06:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: