【问题标题】:Setting a field to read-only in Rails after it's created创建后在 Rails 中将字段设置为只读
【发布时间】:2010-09-26 14:54:40
【问题描述】:

我想在初始创建后保护字段中用户生成的条目。

我在用户设置项目时要求他们提供唯一名称,并且我想在创建后停止更改。

有没有办法在 Rails 中做到这一点?我可以先将其设置为 attr_accessible 然后将其切换为 attr_protected 吗?

干杯

【问题讨论】:

    标签: ruby-on-rails model


    【解决方案1】:

    您可以为模型添加自定义验证方法:

    # Project model
    validate :forbid_changing_name, on: :update
    
    private
    
    def forbid_changing_name
      errors.add :name, "can not be changed!" if self.name_changed?
    end
    

    【讨论】:

    • 这是一个有趣的解决问题的方法;我的赞美。您对这个答案的反对意见,包括我自己,似乎与 SO 的精神背道而驰。
    • @Jesse:不要把它当作个人。我不喜欢投反对票,只有当我认为这确实是错误的答案时才使用它。我希望我对您的回答的另一条评论可以解释这一点。
    • 感谢 klew - 这是我没想到的解决方案。干杯!
    • 值得注意的是,从 rails 3.2 起 validate_on_update :foo, 已被 validate :foo, on: :update 取代
    【解决方案2】:

    如何将其设置为只读? attr_readonly 方法允许您这样做,请参阅:

    API Docs

    【讨论】:

    • 重要说明,正如 API 文档所指定的:attr_readonly 不会阻止您在运行时分配属性,而是在保存期间默默地忽略它。至少,显式错误可能比这种行为更可取。另一个可取的选择是在它不是新记录时完全禁止写入。
    【解决方案3】:

    我会将其设置为 :attr_protected 并创建一个新的“新”方法:

    def self.my_new(attributes = {})
      obj = new(attributes)
      obj.my_protected_attribute = attributes[:protected_attribute]
      obj
    end
    

    【讨论】:

      【解决方案4】:

      如果我要这样做,我会在客户端使用 javascripts 来做。 例如:创建一个javascript函数,在用户输入值后将文本框属性设置为只读。正如我所看到的那样,客户端有两个优势

      1 - 你不想通过服务器轮来锁定值 2 - 您可以灵活地允许用户根据需要更改值(通过单击按钮或其他东西)

      干杯

      同样的

      【讨论】:

      • -1 这是“安全”风险;)。它可以在客户端进行保护,但也必须在服务器端进行保护
      【解决方案5】:

      如果您知道属性的名称,您也可以在控制器中处理它

      class MyModel < ActiveRecord::Base
        attr_protected :super_cool
      end
      

      然后在控制器中:

      def create
        @my_model = MyModel.create(params[:my_model])
        @my_model.super_cool = params[:my_model][:super_cool] unless params[:my_model].nil?
        if @my_model.save
          ..
        else
          ..
        end
      end
      

      【讨论】:

      • @klew -- 你解释一下你的主张吗?这似乎不是必须在控制器中。
      • 这是模型相关的逻辑,它应该留在模型中。如果您确实在模型中关心它,那么您可以在控制器中使用它而无需考虑它。例如,如果他将使用一些嵌套表单并通过某个父对象保存此对象,您的代码将无法完成这项工作。在这种情况下,您必须向控制器添加更多逻辑以了解所有可能的情况。记住:胖模型,瘦控制器。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-10
      • 1970-01-01
      相关资源
      最近更新 更多