【问题标题】:ActiveRecord : Hide column while returning objectActiveRecord : 返回对象时隐藏列
【发布时间】:2013-05-02 16:08:32
【问题描述】:

在返回 ActiveRecord 对象时,是否有一种开箱即用的方法来始终隐藏/删除列(例如,User.password)?

【问题讨论】:

  • 在什么情况下?这是一个 JSON API 吗? Rails 控制台?如果是后者,您将无能为力,因为用户可以有效地访问源代码和数据库。
  • @ZachKemp JSON API。最准确地说,是 OAuth 令牌。我想添加一个 1-1 关系只是为了存储它,但考虑过先询问是否有一种简洁的方法。
  • 你用什么来序列化你的用户模型(即你的api是如何实现的)?
  • @ZachKemp 从数据库中检索数据 (User.find(:id)) 并将对象传递给控制器​​,控制器呈现为 JSON render :json => @users
  • 您没有使用纯文本密码,是吗?否则你就知道要改变什么了。

标签: ruby-on-rails ruby-on-rails-3 activerecord rails-activerecord


【解决方案1】:

使用内置序列化,您可以覆盖模型上的 as_json 方法以传入其他默认选项:

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

可能有更好的序列化工具 - 如果您正在寻找更细粒度的控制,我建议您查看 active_model_serializersrabl

【讨论】:

  • 我会结帐active_model_serializers。但覆盖as_json 是我一直在寻找的。谢谢!
  • 这解决了问题,但如果我这样做@manager.to_json(include: :user) 我仍然会在用户对象中获得密码摘要
  • 是的,我仍然和@Sandeep 说的一样,有什么解决方案吗??
  • nil:NilClass 的未定义方法“合并”
【解决方案2】:

您是否因为试图隐藏纯文本密码而进入此页面?

停止!你做错了。

您不应该、永远不要以纯文本形式保存密码。

您的服务器可能存在或将存在某种缺陷,黑客会获取您的客户端密码。想了想:

  • 你会告诉他们什么?
  • 他们会有什么反应?
  • 您的业务取得了哪些成果?

由于您现在是一个新人并且正在寻找存储密码的正确方法,您可能会want to read this nice article

【讨论】:

  • 即使是 MD5/加密密码,正如我所说,在 API 视图中返回它们也是相当愚蠢的 :)
  • 是的,这不适合你——我在这个问题上阅读了你的 cmets。它是为谷歌到这里的人准备的。
【解决方案3】:

您可以在序列化时使用: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

【讨论】:

  • 谢谢。我目前正在使用except 的条件布局,但after_initialize 似乎很整洁。
【解决方案4】:

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>

【讨论】:

    猜你喜欢
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 2023-02-24
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    相关资源
    最近更新 更多