gjb*_*gjb 27 ruby-on-rails ruby-on-rails-3
我有以下Rails模型:
class CreateFoo < ActiveRecord::Migration
def self.up
create_table :foo do |t|
t.string :a
t.string :b
t.string :c
t.timestamps
end
end
def self.down
drop_table :foo
end
end
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用其他不存在的属性创建新记录,则会产生错误:
Foo.create(a: 'some', b: 'string', c: 'foo', d: 'bar')
ActiveRecord::UnknownAttributeError: unknown attribute: d
Run Code Online (Sandbox Code Playgroud)
有没有办法让create()忽略模型中不存在的属性?或者,在创建新记录之前删除不存在的属性的最佳方法是什么?
非常感谢
jen*_*233 39
试着想出一种可能更有效的方法,但目前:
hash = { :a => 'some', :b => 'string', :c => 'foo', :d => 'bar' }
@something = Something.new
@something.attributes = hash.reject{|k,v| !@something.attributes.keys.member?(k.to_s) }
@something.save
Run Code Online (Sandbox Code Playgroud)
小智 11
我经常使用(简化):
params.select!{|x| Model.attribute_names.index(x)}
Model.update_attributes(params)
Run Code Online (Sandbox Code Playgroud)
您可以使用Hash#slice该方法,该column_names方法也作为类方法存在。
hash = {a: 'some', b: 'string', c: 'foo', d: 'bar'}
Foo.create(hash.slice(*Foo.column_names.map(&:to_sym)))
Run Code Online (Sandbox Code Playgroud)
我刚刚将这个确切的问题升级到Rails 3.2,当我设置:
config.active_record.mass_assignment_sanitizer = :strict
Run Code Online (Sandbox Code Playgroud)
它引起了我的一些创造!调用失败,因为先前被忽略的字段现在导致批量分配错误.我通过伪造模型中的字段来解决这个问题,如下所示:
attr_accessor :field_to_exclude
attr_accessible :field_to_exclude
Run Code Online (Sandbox Code Playgroud)
Re:有没有办法让create()忽略模型中不存在的属性? - 不,这是设计的.
你可以创建一个attr_setter,它将被create-
attr_setter :a # will silently absorb additional parameter 'a' from the form.
Run Code Online (Sandbox Code Playgroud)
Re:或者,在创建新记录之前删除不存在的属性的最佳方法是什么?
您可以明确删除它们:
params[:Foo].delete(:a) # delete the extra param :a
Run Code Online (Sandbox Code Playgroud)
但最好的办法是不要把它们放在首位.修改您的表单以省略它们.
添加:
鉴于更新的信息(传入数据),我想我会创建一个新的哈希:
incoming_data_array.each{|rec|
Foo.create {:a => rec['a'], :b => rec['b'], :c => rec['c']} # create new
# rec from specific
# fields
}
Run Code Online (Sandbox Code Playgroud)
添加更多
# Another way:
keepers = ['a', 'b', 'c'] # fields used by the Foo class.
incoming_data_array.each{|rec|
Foo.create rec.delete_if{|key, value| !keepers.include?(key)} # create new rec
} # from kept
# fields
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13756 次 |
| 最近记录: |