ActiveRecord: скрыть столбец при возврате объекта

Есть ли нестандартный способ всегда скрывать / удалять столбец (скажем, User.password) при возврате объекта ActiveRecord?


person zakelfassi    schedule 02.05.2013    source источник
comment
В каком контексте? Это API JSON? Консоль Rails? В последнем случае вы ничего не можете сделать, поскольку пользователь фактически имеет доступ к исходному коду и базе данных.   -  person Zach Kemp    schedule 02.05.2013
comment
@ZachKemp JSON Api. Точнее, токен OAuth. Я подумал о добавлении отношения 1-1, чтобы сохранить это, но подумал сначала спросить, есть ли изящный способ.   -  person zakelfassi    schedule 02.05.2013
comment
Что вы используете для сериализации своей пользовательской модели (например, как реализован ваш API)?   -  person Zach Kemp    schedule 02.05.2013
comment
@ZachKemp извлекает данные из базы данных (User.find (: id)) и передает объекты контроллеру, который отображается как JSON render :json => @users   -  person zakelfassi    schedule 02.05.2013
comment
Вы ведь не используете пароли в виде простого текста? иначе вы точно знаете, что нужно изменить.   -  person fotanus    schedule 02.05.2013
comment
+1 @fotanus, но вопрос может относиться к другим атрибутам, которые не следует / не нужно сериализовать   -  person PinnyM    schedule 02.05.2013
comment
@fotanus Даже для зашифрованных паролей было бы глупо возвращать их в API! Но в данном случае это токены Facebook OAuth (которые могут быть легко украдены в случае возврата).   -  person zakelfassi    schedule 02.05.2013


Ответы (4)


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

class User < ActiveRecord::Base
  # ...
  def as_json(options = {})
    super(options.merge({ except: [:password, :oauth_token] }))
  end
end

Вероятно, существуют лучшие инструменты сериализации - если вы ищете более детальный контроль, я бы рекомендовал проверить active_model_serializers или rabl.

person Zach Kemp    schedule 02.05.2013
comment
Я проверю active_model_serializers. Но переопределение as_json - это то, что я искал. Спасибо ! - person zakelfassi; 02.05.2013
comment
Это решает проблему, но если я сделаю что-то подобное @manager.to_json(include: :user), я все равно получаю файл password_digest, сохраненный в объекте пользователя. - person Sandeep; 11.04.2017
comment
да, я все еще получаю то же самое, что сказал @Sandeep, любое решение ?? - person Jai Kumar Rajput; 14.06.2017
comment
неопределенный метод `merge 'для nil: NilClass - person Frank Fang; 04.03.2020

Вы попали на эту страницу, потому что пытаетесь скрыть пароли в виде простого текста?

СТОП! вы делаете это неправильно.

Никогда не храните пароли в виде обычного текста.

Скорее всего, ваш сервер имеет или будет иметь какой-то недостаток, и хакеры получат пароли ваших клиентов. Подумайте немного:

  • Что ты им скажешь?
  • Как они отреагируют?
  • Каковы результаты для вашего бизнеса?

Поскольку вы теперь новый человек и ищете правильный способ хранения паролей, вы можете хочу прочитать эту красивую статью

person fotanus    schedule 02.05.2013
comment
Даже для MD5 / зашифрованных паролей, как я уже сказал, было бы довольно глупо возвращать их в представлении API :) - person zakelfassi; 02.05.2013
comment
Да это не для вас - я читал ваши комментарии к вопросу. Это для людей, которые ищут здесь в Google. - person fotanus; 02.05.2013

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

render json: @users, except: [:password, :other]

Кроме того, вы можете использовать для этого after_initialize и переместить данные в не- сериализованный атрибут:

class User < ActiveRecord::Base
  attr_accessor :hidden_password, :hidden_other
  after_initialize :hide_columns

  def hide_columns
    [:password, :other].each do |c|
      send("hidden_#{c}=", send(c))
      send("#{c}=", nil)
    end
  end
end
person PinnyM    schedule 02.05.2013
comment
Спасибо за это. В настоящее время я использую условный макет с except, но after_initialize кажется аккуратным. - person zakelfassi; 02.05.2013

Спустя 8 лет в Rails 5+ появился способ игнорировать / скрывать столбцы из модели:

ActiveRecord::Migration.new.create_table :my_pages do |t|
  t.string :title
  t.string :body
  t.string :search_tsv
end

class MyPage < ActiveRecord::Base
  self.ignored_columns = %w[search_tsv]
end

MyPage.new

# => #<MyPage:0x00007fa4693b8278 id: nil, title: nil, body: nil>

class MyPage2 < ActiveRecord::Base
  self.table_name = 'my_pages'
  self.ignored_columns = %w[body search_tsv]
end

MyPage2.new

# => #<MyPage2:0x00007fa46845f808 id: nil, title: nil>
person Xiaohui Zhang    schedule 22.07.2021