2012-07-19 21 views
2

我正在通过使用rails第4版(rails 3.2+)的敏捷web开发工作,并且有一个关于migraitons的问题。有一个练习,我必须将列添加到现有表中,然后使用值更新该新列。我需要在'line_items'表中添加'价格'列。首先,我产生的迁移:attr_accessible在迁移

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中指定。任何和所有的输入将不胜感激。

回答

3

Basicaly没有影响那是因为在轨形成,你可以任意字段添加到表单。如果用户向表单添加新参数并将其提交给服务器,它可能会给您带来很大的问题。

像这样:

控制器:

LineItem.create(params[:line_item) 

,如果这是你的控制器的用户接入(通过JavaScript或通过镀铬控制台编辑)一个新的文本框,他可以修改受保护的领域。

那就是为什么我们使用attr_accessible只允许defioned字段。

所以不在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它有一个很好的解释

2

attr_accessible控制你做的事情一样

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

这是什么控制器升级/创建方法通常做的能力。

它有

some_line_item.foo = bar