Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define record to let ValidateableObject access the outer model #13

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/validates_serialized/validateable_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

class ValidateableObject
include ::ActiveModel::Validations
attr_reader :record

def initialize(object)
def initialize(object, record)
@object = object
@record = record
@record = @record.record while @record.is_a? ValidateableObject
end

def self.method_missing(method, *args, &block)
Expand Down
10 changes: 5 additions & 5 deletions lib/validates_serialized/validators/array_block_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ def initialize(options, &block)
private
def validate_each(record, attribute, array)
raise TypeError, "#{attribute} is not an Array" unless array.is_a?(Array)
errors = get_serialized_object_errors(array)
errors = get_serialized_object_errors(array, record)
add_errors_to_record(record, attribute, errors)
end

def build_serialized_object(value)
def build_serialized_object(value, record)
#TODO: For the Rails 4 version, I can just clear_validators! on the ValidateableHash
temp_class = Class.new(ValidateableArrayValue)
temp_class_name = "ValidateableArrayValue_#{SecureRandom.hex}"
if self.class.constants.include?(temp_class_name)
self.class.send(:remove_const, temp_class_name)
end
self.class.const_set(temp_class_name, temp_class)
temp_class.new(value)
temp_class.new(value, record)
end

def get_serialized_object_errors(array)
def get_serialized_object_errors(array, record)
messages = []
array.each do |value|
serialized_object = build_serialized_object(value)
serialized_object = build_serialized_object(value, record)
serialized_object.class_eval &@block
serialized_object.valid?
message = serialized_object.errors.messages[:value]
Expand Down
10 changes: 5 additions & 5 deletions lib/validates_serialized/validators/hash_block_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ def initialize(options, &block)
private
def validate_each(record, attribute, value)
raise TypeError, "#{attribute} is not a Hash" unless value.is_a?(Hash)
error_hash = get_serialized_object_errors(value)
error_hash = get_serialized_object_errors(value, record)
add_errors_to_record(record, attribute, error_hash)
ValidateableHash.clear_validators!
end

def build_serialized_object(value)
def build_serialized_object(value, record)
ValidateableHash.clear_validators!
ValidateableHash.new(value)
ValidateableHash.new(value, record)
end

def get_serialized_object_errors(value)
serialized_object = build_serialized_object(value)
def get_serialized_object_errors(value, record)
serialized_object = build_serialized_object(value, record)
serialized_object.class_eval &@block
serialized_object.valid?
serialized_object.errors.messages
Expand Down
10 changes: 5 additions & 5 deletions lib/validates_serialized/validators/object_block_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ def initialize(options, &block)

private
def validate_each(record, attribute, value)
error_hash = get_serialized_object_errors(value)
error_hash = get_serialized_object_errors(value, record)
add_errors_to_record(record, attribute, error_hash)
ValidateableObject.clear_validators!
end

def build_serialized_object(value)
def build_serialized_object(value, record)
ValidateableObject.clear_validators!
ValidateableObject.new(value)
ValidateableObject.new(value, record)
end

def get_serialized_object_errors(value)
serialized_object = build_serialized_object(value)
def get_serialized_object_errors(value, record)
serialized_object = build_serialized_object(value, record)
serialized_object.class_eval &@block
serialized_object.valid?
serialized_object.errors.messages
Expand Down
97 changes: 54 additions & 43 deletions spec/acceptance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,46 +33,14 @@ class Blog

def initialize(h={})
h.each {|k,v| send("#{k}=",v)}
@enforce_min_length = true
end

def author
@author
end

def author=(val)
@author = val
end

def ratings
@ratings
end

def ratings=(val)
@ratings = val
end

def tags
@tags
end
attr_accessor :author, :ratings, :tags, :comments, :metadata, :data
attr_accessor :enforce_min_length

def tags=(val)
@tags = val
end

def comments
@comments
end

def comments=(val)
@comments = val
end

def metadata
@metadata
end

def metadata=(val)
@metadata = val
def needs_uuid?
true
end

validates_serialized :author do
Expand All @@ -86,18 +54,28 @@ def metadata=(val)
end

validates_each_in_array :metadata, if: :metadata do
validates_hash_keys :value do
validates_hash_keys :value do
validates :timestamp, presence: true
end
end

validates_hash_keys :comments, allow_blank: true do
validates_hash_keys :comments, allow_blank: true do
validates :admin, presence: true
end

# validates_hash_keys :data, allow_blank: true do
# validates :url, presence: true, if: Proc.new{|f| f.required_data_field?(:url) }
# end
validates_hash_keys :data, allow_blank: true do
validates :url, presence: true, if: Proc.new{ |hsh| hsh.needs_url }
validates :date, presence: true, if: Proc.new{ |hsh| hsh[:needs_date] }
validates :slug, presence: true, if: :needs_slug?
validates :uuid, presence: true, if: Proc.new{ |hsh| hsh.record.needs_uuid? }
validates_each_in_array :posts, allow_blank: true do
validates :value, length: { minimum: 5, if: Proc.new { |arr| arr.record.enforce_min_length } }
end

def needs_slug?
true
end
end
end

describe ValidatesSerialized do
Expand Down Expand Up @@ -154,4 +132,37 @@ def metadata=(val)
model.should_not be_valid
model.errors[:tags].should eq(["tags has a value that is too short (minimum is 4 characters)"])
end
end

it "is valid with dependent hash keys" do
model = Blog.new(ratings: [1, 3, 1], author: Author.new(name: "Tom"),
data: { url: 'http://example.com',
needs_url: true,
date: 'yesterday',
needs_date: true,
slug: 'blog-name',
uuid: '123-abc-456-def' })
model.should be_valid
end

it "is valid with dependent nested array values" do
model = Blog.new(ratings: [1, 3, 1], author: Author.new(name: "Tom"), data: { posts: %w[hello world fantastic], uuid: '123-abc-456-def', slug: 'blog-name' })
model.should be_valid

model = Blog.new(ratings: [1, 3, 1], author: Author.new(name: "Tom"), data: { posts: %w[wow], uuid: '123-abc-456-def', slug: 'blog-name' })
model.enforce_min_length = false
model.should be_valid
end

it "is invalid with missing dependent hash keys" do
model = Blog.new(ratings: [1, 3, 1], author: Author.new(name: "Tom"),
data: { needs_url: true,
needs_date: true })
model.should_not be_valid
model.errors.details[:data].map { |err| err[:error].split[0] }.sort.should eql %w[date slug url uuid]
end

it "is invalid with incorrect dependent nested array values" do
model = Blog.new(ratings: [1, 3, 1], author: Author.new(name: "Tom"), data: { posts: %w[wow], uuid: '123-abc-456-def', slug: 'blog-name' })
model.should_not be_valid
end
end