diff --git a/lib/sequel/model/base.rb b/lib/sequel/model/base.rb index 1c1a6f1f3..1d5507589 100644 --- a/lib/sequel/model/base.rb +++ b/lib/sequel/model/base.rb @@ -2038,12 +2038,12 @@ def set_restricted(hash, type) # Avoid using respond_to? or creating symbols from user input if public_methods.map(&:to_s).include?(m) if Array(model.primary_key).map(&:to_s).member?(k.to_s) && model.restrict_primary_key? - raise MassAssignmentRestriction, "#{k} is a restricted primary key" + raise MassAssignmentRestriction.create("#{k} is a restricted primary key", self) else - raise MassAssignmentRestriction, "#{k} is a restricted column" + raise MassAssignmentRestriction.create("#{k} is a restricted column", self) end else - raise MassAssignmentRestriction, "method #{m} doesn't exist" + raise MassAssignmentRestriction.create("method #{m} doesn't exist", self) end end end diff --git a/lib/sequel/model/exceptions.rb b/lib/sequel/model/exceptions.rb index 81aabacb2..72a5a98f5 100644 --- a/lib/sequel/model/exceptions.rb +++ b/lib/sequel/model/exceptions.rb @@ -24,11 +24,19 @@ def initialize(message=nil, model=nil) UndefinedAssociation = Class.new(Error) ).name - ( # Raised when a mass assignment method is called in strict mode with either a restricted column # or a column without a setter method. - MassAssignmentRestriction = Class.new(Error) - ).name + class MassAssignmentRestriction < Error + # The Sequel::Model object related to this exception. + attr_reader :model + + def self.create(msg, model) + msg += " for class #{model.class.name}" if model.class.name + new(msg).tap do |err| + err.instance_variable_set(:@model, model) + end + end + end # Exception class raised when +raise_on_save_failure+ is set and validation fails class ValidationFailed < Error diff --git a/spec/extensions/csv_serializer_spec.rb b/spec/extensions/csv_serializer_spec.rb index 968eaf3bc..08bccc74d 100644 --- a/spec/extensions/csv_serializer_spec.rb +++ b/spec/extensions/csv_serializer_spec.rb @@ -163,7 +163,8 @@ def self.name; 'Album' end it "should raise an error if attempting to set a restricted column and :all_columns is not used" do @Artist.restrict_primary_key - proc{@Artist.from_csv(@artist.to_csv)}.must_raise(Sequel::MassAssignmentRestriction) + err = proc{@Artist.from_csv(@artist.to_csv)}.must_raise(Sequel::MassAssignmentRestriction) + err.message.must_equal("id is a restricted primary key for class Artist") end it "should use a dataset's selected columns" do diff --git a/spec/model/base_spec.rb b/spec/model/base_spec.rb index 78c29bd49..811c9a991 100644 --- a/spec/model/base_spec.rb +++ b/spec/model/base_spec.rb @@ -664,13 +664,28 @@ class ModelTest2 < Sequel::Model(@db[:foo]) end it "should raise an error if a missing/restricted column/method is accessed" do - proc{@c.new(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction) + err = proc{@c.new(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction) + err.message.must_equal("method a= doesn't exist") proc{@c.create(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction) c = @c.new proc{c.set(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction) proc{c.update(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction) end + it "should add class name to error message" do + item = Class.new(Sequel::Model(:items)) do + columns :id + end + + item.class_eval do + def self.name; 'Item' end + end + + err = proc{item.new(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction) + err.message.must_equal("method a= doesn't exist for class Item") + err.model.class.must_equal(item) + end + it "should be disabled by strict_param_setting = false" do @c.strict_param_setting = false @c.strict_param_setting.must_equal false diff --git a/spec/model/exceptions_spec.rb b/spec/model/exceptions_spec.rb new file mode 100644 index 000000000..cc0f2ee02 --- /dev/null +++ b/spec/model/exceptions_spec.rb @@ -0,0 +1,15 @@ +require_relative "spec_helper" + +describe Sequel::MassAssignmentRestriction, "#create" do + it "should set model attr" do + model_cls = Class.new + model_cls.class_eval do + def self.name; 'TestModel' end + end + + model = model_cls.new + err = Sequel::MassAssignmentRestriction.create("method foo doesn't exist", model) + err.message.must_equal("method foo doesn't exist for class TestModel") + err.model.must_equal(model) + end +end