I have the following Rails model:
class CreateFoo < ActiveRecord::Migration
def self.up
create_table :foo do |t|
t.string :a
t.string :b
You can use Hash#slice
and column_names
method exists also as class method.
hash = {a: 'some', b: 'string', c: 'foo', d: 'bar'}
Foo.create(hash.slice(*Foo.column_names.map(&:to_sym)))
I use this frequently (simplified):
params.select!{|x| Model.attribute_names.index(x)}
Model.update_attributes(params)
I think using the attr_accessible method in the model class for Foo would achieve what you want, e.g.,:
class Foo < ActiveRecord::Base
attr_accessible :a, :b, :c
...
end
This would allow the setting/updating of only those attributes listed with attr_accessible.
I found a solution that works fairly well, and is ultimately a combination of the above options. It allows for invalid params to be passed (and ignored), while valid ones are mapped correctly to the object.
def self.initialize(params={})
User.new(params.reject { |k| !User.attribute_method?(k) })
end
Now rather than calling User.new()
, call User.initialize()
. This will "filter" the correct params fairly elegantly.
I came up with a solution that looks like this, you might find it helpful:
def self.create_from_hash(hash)
hash.select! {|k, v| self.column_names.include? k }
self.create(hash)
end
This was an ideal solution for me, because in my case hash
was coming from an ideal data source which mirrored my schema (except there were additional fields).
I just had this exact problem upgrading to Rails 3.2, when I set:
config.active_record.mass_assignment_sanitizer = :strict
It caused some of my create! calls to fail, since fields that were previously ignored are now causing mass assignment errors. I worked around it by faking the fields in the model as follows:
attr_accessor :field_to_exclude
attr_accessible :field_to_exclude