2

我正在使用 rails 4th edition (rails 3.2+) 进行敏捷 Web 开发,并且有一个关于 migraitons 的问题。有一个练习,我必须在现有表中添加一列,然后用值更新该新列。我需要在 'line_items' 表中添加一个 'price' 列。首先我生成了迁移:

rails generate migration add_price_to_line_items price:decimal

然后我编辑了迁移文件:

class AddPriceToLineItems < ActiveRecord::Migration
  def change
    add_column :line_items, :price, :decimal

    LineItem.all.each do |li|
      li.price = li.product.price
    end
  end

  def down 
    remove_column :line_items, :price
  end
end

一切都按计划进行,但是,我有一个关于 attr_accessible 的问题。据我了解,对象的所有属性都需要在 attr_accessible 中指定才能进行编辑。如果没有,您通常会收到此错误:

ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: product

因此,所有属性都必须在关联模型中设置为 attr_accessible 的参数:

class LineItem < ActiveRecord::Base
  **attr_accessible :cart_id, :product_id, :quantity**
  belongs_to :cart
  belongs_to :product

  def total_price
    product.price * quantity
  end

end

如果这是真的,那么我的迁移如何能够更新新生成的列?如果该列刚刚生成,则该新属性尚未在关联模型的 attr_accessible 中指定。任何和所有输入将不胜感激。

4

2 回答 2

3

基本上这是因为在 Rails 表单中,您可以将任何字段添加到表单中。如果用户向表单添加新参数并将其提交到您的服务器,它会给您带来很大的问题。

像这样:

你的控制器:

LineItem.create(params[:line_item)

如果这是您的控制器,则用户插入(通过 javascript 或通过 chrome 上的控制台编辑)一个新的文本字段,他可以修改受保护的字段。

这就是为什么我们attr_accessible过去只允许定义字段。

所以不在的attr_accessible属性仍然可以访问,只是无法进行质量分配。

你仍然可以做这样的事情:

模型有名称、时间和日期:

attr_accessible :name, :time

控制器或任何类:

你可以:

m = Model.new(:name => "name", :time => "time")
m.date = "date"
m.save

你不能:

m = Model.new(:name => "name", :time => "time", :date = "date")
m.save

如果您仍然不明白,请查看此链接http://ruby.railstutorial.org/chapters/modeling-users#sec:accessible_attributes它有一个很好的解释

于 2012-07-19T12:33:02.357 回答
2

attr_accessible控制你做事情的能力,比如

LineItem.create(:foo => bar)
some_line_item.update_attributes(:foo => bar)

这是控制器更新/创建方法通常所做的。

它对

some_line_item.foo = bar
于 2012-07-19T12:19:25.160 回答