如何覆盖 attr_protected?

发布于 2024-08-26 22:39:42 字数 763 浏览 14 评论 0原文

我的 STI 实现如下:

class Automobile < ActiveRecord::Base
end

class Car < Automobile
end

class Truck < Automobile
end

class User < ActiveRecord::Base
  has_many :automobiles
  accepts_nested_attributes_for :automobiles
end

我正在为用户创建汽车列表。对于每辆汽车,UI 都会设置 type 字段以及与汽车关联的属性。提交表单时,type 字段将被忽略,因为它是受保护的属性。

我该如何解决这个问题?是否有一种声明性方式来取消保护受保护的属性?

编辑: 这是我目前的问题解决方案: 我在模型类中重写了 attributes_protected_by_default 私有方法。

class Automobile < ActiveRecord::Base
private
  def attributes_protected_by_default
    super - [self.class.inheritance_column]
  end
end

这将从受保护列表中删除 type 字段。

我希望有比这更好的方法。

I have STI implementation as follows:

class Automobile < ActiveRecord::Base
end

class Car < Automobile
end

class Truck < Automobile
end

class User < ActiveRecord::Base
  has_many :automobiles
  accepts_nested_attributes_for :automobiles
end

I am creating a list of automobiles for a user. For each automobile, the UI sets the type field and the properties associated with the automobile.While form submission, the type field is ignored as it is a protected attribute.

How do I work around this issue? Is there a declarative way to unprotect a protected attribute?

Edit:
This is my current solution for the problem:
I override the attributes_protected_by_default private method in my model class.

class Automobile < ActiveRecord::Base
private
  def attributes_protected_by_default
    super - [self.class.inheritance_column]
  end
end

This removes the type field from the protected list.

I am hoping that there is a better way than this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

昵称有卵用 2024-09-02 22:39:42

我最终这样做了:

class Automobile < ActiveRecord::Base
private
  def attributes_protected_by_default
    super - [self.class.inheritance_column]
  end
end

I ended up doing this:

class Automobile < ActiveRecord::Base
private
  def attributes_protected_by_default
    super - [self.class.inheritance_column]
  end
end
苦笑流年记忆 2024-09-02 22:39:42

我会在 User 上添加一个帮助器方法来实例化适当的子类:

class User < ActiveRecord::Base
  def self.automobile_from_type(type)
    self.automobiles << case type
    when "Car"
      Car.new
    when "Truck"
      Truck.new
    else
      raise ArgumentError, "Unknown automobile type: #{type.inspect}"
    end
  end
end

像这样使用它:

class AutomobilesController < ApplicationController
  def create
    @automobile = current_user.automobile_from_type(params[:automobile][:type])
    if @automobile.update_attributes(params[:automobile]) then
      redirect_to @automobile
    else
      render :action => :new
    end
  end
end

上面的代码是“安全的”:攻击者无法将任意文本注入到 cars.type 列中。您的解决方案虽然有效,但存在引发攻击的缺点。

I would add a helper method on User that instantiates the appropriate subclass:

class User < ActiveRecord::Base
  def self.automobile_from_type(type)
    self.automobiles << case type
    when "Car"
      Car.new
    when "Truck"
      Truck.new
    else
      raise ArgumentError, "Unknown automobile type: #{type.inspect}"
    end
  end
end

Use it like this:

class AutomobilesController < ApplicationController
  def create
    @automobile = current_user.automobile_from_type(params[:automobile][:type])
    if @automobile.update_attributes(params[:automobile]) then
      redirect_to @automobile
    else
      render :action => :new
    end
  end
end

The code above is "safe": an attacker can't inject arbitrary text into your automobiles.type column. Your solution, while it works, has the disadvantage of enabling attacks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文