-
Notifications
You must be signed in to change notification settings - Fork 23
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
Add support for validations #29
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,9 +176,9 @@ def readonly? | |
# | ||
# Also runs any before/after save callbacks that are defined. | ||
# | ||
def save | ||
def save(*args) | ||
run_callbacks :save do | ||
create_or_update | ||
create_or_update(*args) | ||
end | ||
end | ||
|
||
|
@@ -192,8 +192,8 @@ def save | |
# | ||
# Also runs any before/after save callbacks that are defined. | ||
# | ||
def save! | ||
save || raise(RemoteRecordNotSaved) | ||
def save!(*args) | ||
save(*args) || raise(RemoteRecordNotSaved) | ||
end | ||
|
||
# Returns true if the record doesn't have errors; otherwise, returns false. | ||
|
@@ -245,9 +245,9 @@ def create | |
# are created, existing records are updated. If the record is marked as | ||
# readonly, an ActiveRemote::ReadOnlyRemoteRecord is raised. | ||
# | ||
def create_or_update | ||
def create_or_update(*args) | ||
raise ReadOnlyRemoteRecord if readonly? | ||
new_record? ? create : update | ||
new_record? ? create : update(*args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not splat the args on create as well? Does it not support skipping validations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, after looking at this again, I'm not sure that either of these need to take args. Is there some AR functionality that this is replicating that I'm not aware of? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just structured it like ActiveRecord There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weird. I'm guessing they're doing that so the method arity doesn't change when dirty tracking is included. |
||
end | ||
|
||
# Handles updating a remote object and serializing it's attributes and | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
module ActiveRemote | ||
module Validations | ||
extend ActiveSupport::Concern | ||
|
||
# Attempts to save the record like Persistence, but will run | ||
# validations and return false if the record is invalid | ||
# | ||
# Validations can be skipped by passing :validate => false | ||
# | ||
# example Save a record | ||
# post.save | ||
# | ||
# example Save a record, skip validations | ||
# post.save(:validate => false) | ||
# | ||
def save(options = {}) | ||
perform_validations(options) ? super : false | ||
end | ||
|
||
# Attempts to save the record like Persistence, but will raise | ||
# ActiveRemote::RemoteRecordInvalid if the record is not valid | ||
# | ||
# Validations can be skipped by passing :validate => false | ||
# | ||
# example Save a record, raise and error if invalid | ||
# post.save! | ||
# | ||
# example Save a record, skip validations | ||
# post.save!(:validate => false) | ||
# | ||
def save!(options = {}) | ||
perform_validations(options) ? super : raise_validation_error | ||
end | ||
|
||
# Runs all the validations within the specified context. Returns true if | ||
# no errors are found, false otherwise. | ||
# | ||
# Aliased as validate. | ||
# | ||
# example Is the record valid? | ||
# post.valid? | ||
# | ||
# example Is the record valid for creation? | ||
# post.valid?(:create) | ||
# | ||
def valid?(context = nil) | ||
context ||= (new_record? ? :create : :update) | ||
output = super(context) | ||
errors.empty? && output | ||
end | ||
|
||
alias_method :validate, :valid? | ||
|
||
protected | ||
|
||
def raise_validation_error | ||
fail(::ActiveRemote::RemoteRecordInvalid.new(self)) | ||
end | ||
|
||
def perform_validations(options = {}) | ||
options[:validate] == false || valid?(options[:context]) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
require 'spec_helper' | ||
|
||
describe ActiveRemote::Validations do | ||
let(:invalid_record) { ::Post.new } | ||
let(:valid_record) { ::Post.new(:name => 'test') } | ||
|
||
before { valid_record.stub(:create_or_update).and_return(true) } | ||
before { invalid_record.stub(:create_or_update).and_return(true) } | ||
|
||
describe 'save' do | ||
context 'valid record' do | ||
it 'returns true' do | ||
result = valid_record.save | ||
result.should be true | ||
end | ||
end | ||
|
||
context 'invalid record' do | ||
it 'returns false' do | ||
result = invalid_record.save | ||
result.should be false | ||
end | ||
end | ||
end | ||
|
||
describe 'save!' do | ||
context 'valid record' do | ||
it 'returns true' do | ||
result = valid_record.save! | ||
result.should be true | ||
end | ||
end | ||
|
||
context 'invalid record' do | ||
it 'raises invalid record error' do | ||
expect { invalid_record.save! }.to raise_error(ActiveRemote::RemoteRecordInvalid) | ||
end | ||
end | ||
end | ||
|
||
describe 'valid?' do | ||
context 'valid record' do | ||
it 'returns true' do | ||
result = valid_record.valid? | ||
result.should be true | ||
end | ||
end | ||
|
||
context 'invalid record' do | ||
it 'returns false' do | ||
result = invalid_record.valid? | ||
result.should be false | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does including this after
Dirty
cause any issues with the dirty tracking?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking at the
Validations
module, this shouldn't be an issue since it callssuper
. However, if there are not specs around this already, it might a good idea to add some to verify.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can go before or after Dirty, but it must be after Persistence
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍