diff options
| -rw-r--r-- | actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb | 2 | ||||
| -rw-r--r-- | activerecord/lib/active_record/autosave_association.rb | 2 | ||||
| -rw-r--r-- | activerecord/test/cases/autosave_association_test.rb | 41 | ||||
| -rw-r--r-- | activerecord/test/models/author.rb | 1 | ||||
| -rw-r--r-- | activerecord/test/models/book.rb | 6 | ||||
| -rw-r--r-- | guides/source/security.md | 2 | 
6 files changed, 52 insertions, 2 deletions
diff --git a/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb b/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb index 1b8ca7bd5e..6fc39c2433 100644 --- a/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb +++ b/actionmailbox/test/controllers/rails/action_mailbox/inbound_emails_controller_test.rb @@ -10,6 +10,7 @@ class Rails::Conductor::ActionMailbox::InboundEmailsControllerTest < ActionDispa            mail: {              from: "Jason Fried <jason@37signals.com>",              to: "Replies <replies@example.com>", +            cc: "CC <cc@example.com>",              bcc: "Bcc <bcc@example.com>",              in_reply_to: "<4e6e35f5a38b4_479f13bb90078178@small-app-01.mail>",              subject: "Hey there", @@ -21,6 +22,7 @@ class Rails::Conductor::ActionMailbox::InboundEmailsControllerTest < ActionDispa        mail = ActionMailbox::InboundEmail.last.mail        assert_equal %w[ jason@37signals.com ], mail.from        assert_equal %w[ replies@example.com ], mail.to +      assert_equal %w[ cc@example.com ], mail.cc        assert_equal %w[ bcc@example.com ], mail.bcc        assert_equal "4e6e35f5a38b4_479f13bb90078178@small-app-01.mail", mail.in_reply_to        assert_equal "Hey there", mail.subject diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index a7709b444d..94d8134b55 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -409,7 +409,7 @@ module ActiveRecord                  saved = record.save(validate: false)                end -              raise ActiveRecord::Rollback unless saved +              raise(RecordInvalid.new(association.owner)) unless saved              end            end          end diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 7e61ac9d8b..2d223a3035 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -2,6 +2,7 @@  require "cases/helper"  require "models/author" +require "models/book"  require "models/bird"  require "models/post"  require "models/comment" @@ -1671,6 +1672,10 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te      super      @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")      @pirate.birds.create(name: "cookoo") + +    @author = Author.new(name: "DHH") +    @author.published_books.build(name: "Rework", isbn: "1234") +    @author.published_books.build(name: "Remote", isbn: "1234")    end    test "should automatically validate associations" do @@ -1679,6 +1684,42 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te      assert_not_predicate @pirate, :valid?    end + +  test "rollbacks whole transaction and raises ActiveRecord::RecordInvalid when associations fail to #save! due to uniqueness validation failure" do +    author_count_before_save = Author.count +    book_count_before_save = Book.count + +    assert_no_difference "Author.count" do +      assert_no_difference "Book.count" do +        exception = assert_raises(ActiveRecord::RecordInvalid) do +          @author.save! +        end + +        assert_equal("Validation failed: Published books is invalid", exception.message) +      end +    end + +    assert_equal(author_count_before_save, Author.count) +    assert_equal(book_count_before_save, Book.count) +  end + +  test "rollbacks whole transaction when associations fail to #save due to uniqueness validation failure" do +    author_count_before_save = Author.count +    book_count_before_save = Book.count + +    assert_no_difference "Author.count" do +      assert_no_difference "Book.count" do +        assert_nothing_raised do +          result = @author.save + +          assert_not(result) +        end +      end +    end + +    assert_equal(author_count_before_save, Author.count) +    assert_equal(book_count_before_save, Book.count) +  end  end  class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index b52b643ad7..da7e4139b1 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -116,6 +116,7 @@ class Author < ActiveRecord::Base    has_many :tags_with_primary_key, through: :posts    has_many :books +  has_many :published_books, class_name: "PublishedBook"    has_many :unpublished_books, -> { where(status: [:proposed, :written]) }, class_name: "Book"    has_many :subscriptions,        through: :books    has_many :subscribers, -> { order("subscribers.nick") }, through: :subscriptions diff --git a/activerecord/test/models/book.rb b/activerecord/test/models/book.rb index afdda1a81e..43b82e6047 100644 --- a/activerecord/test/models/book.rb +++ b/activerecord/test/models/book.rb @@ -24,3 +24,9 @@ class Book < ActiveRecord::Base      "do publish work..."    end  end + +class PublishedBook < ActiveRecord::Base +  self.table_name = "books" + +  validates_uniqueness_of :isbn +end diff --git a/guides/source/security.md b/guides/source/security.md index 22c122d4b9..5bb7a51524 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -1211,4 +1211,4 @@ The security landscape shifts and it is important to keep up to date, because mi  * Subscribe to the Rails security [mailing list](https://groups.google.com/forum/#!forum/rubyonrails-security).  * [Brakeman - Rails Security Scanner](https://brakemanscanner.org/) - To perform static security analysis for Rails applications.  * [Keep up to date on the other application layers](http://secunia.com/) (they have a weekly newsletter, too). -* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet). +* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.md).  | 
