Skip to content

Commit

Permalink
Merge 174422e into 876e636
Browse files Browse the repository at this point in the history
  • Loading branch information
blaze182 committed Sep 18, 2019
2 parents 876e636 + 174422e commit dacdd3e
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

## master

- [PR #35](https://github.com/DmitryTsepelev/store_model/pull/35) Maintain `#parent` reference for StoreModels ([@blaze182][])

## 0.5.3 (2019-09-05)

- [PR #34](https://github.com/DmitryTsepelev/store_model/pull/34) Fix `#unknown_attributes` assignment for `ArrayType` ([@iarie][])
Expand Down Expand Up @@ -59,3 +61,4 @@

[@DmitryTsepelev]: https://github.com/DmitryTsepelev
[@iarie]: https://github.com/iarie
[@blaze182]: https://github.com/blaze182
1 change: 1 addition & 0 deletions lib/store_model.rb
Expand Up @@ -2,6 +2,7 @@

require "store_model/model"
require "store_model/configuration"
require "store_model/railtie"
require "active_model/validations/store_model_validator"

module StoreModel # :nodoc:
Expand Down
24 changes: 24 additions & 0 deletions lib/store_model/ext/active_model/attributes.rb
@@ -0,0 +1,24 @@
# frozen_string_literal: true

require "store_model/ext/parent_assignment"

module StoreModel
# ActiveModel::Attributes patch with parent tracking support
module Attributes
include ParentAssignment

private

def attribute(*)
super.tap do |value|
assign_parent_to_store_model_relation(value)
end
end

def write_attribute(*)
super.tap do |value|
assign_parent_to_store_model_relation(value)
end
end
end
end
22 changes: 22 additions & 0 deletions lib/store_model/ext/active_record/base.rb
@@ -0,0 +1,22 @@
# frozen_string_literal: true

require "store_model/ext/parent_assignment"

module StoreModel
# ActiveRecord::Base patch with parent tracking support
module Base
include ParentAssignment

def _read_attribute(*)
super.tap do |attribute|
assign_parent_to_store_model_relation(attribute)
end
end

def _write_attribute(*)
super.tap do |attribute|
assign_parent_to_store_model_relation(attribute)
end
end
end
end
19 changes: 19 additions & 0 deletions lib/store_model/ext/parent_assignment.rb
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module StoreModel
# Helper methods for ActiveModel and ActiveRecord parent tracking support
module ParentAssignment
private

def assign_parent_to_store_model_relation(attribute)
assign_parent_to_singular_store_model(attribute)
return unless attribute.is_a?(Array)

attribute.each(&method(:assign_parent_to_singular_store_model))
end

def assign_parent_to_singular_store_model(item)
item.parent = self if item.is_a?(StoreModel::Model)
end
end
end
2 changes: 2 additions & 0 deletions lib/store_model/model.rb
Expand Up @@ -17,6 +17,8 @@ def self.included(base) # :nodoc:
base.extend StoreModel::TypeBuilders
end

attr_accessor :parent

# Returns a hash representing the model. Some configuration can be
# passed through +options+.
#
Expand Down
15 changes: 15 additions & 0 deletions lib/store_model/railtie.rb
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require "store_model/ext/active_model/attributes"
require "store_model/ext/active_record/base"

module StoreModel # :nodoc:
class Railtie < Rails::Railtie # :nodoc:
config.to_prepare do |_app|
ActiveSupport.on_load(:active_record) do
ActiveModel::Attributes.prepend(Attributes)
prepend(Base)
end
end
end
end
1 change: 1 addition & 0 deletions spec/dummy/config/application.rb
Expand Up @@ -4,6 +4,7 @@

require "rails"
require "action_controller/railtie"
require "store_model/railtie"

Bundler.require(*Rails.groups)

Expand Down
80 changes: 80 additions & 0 deletions spec/store_model/model_spec.rb
Expand Up @@ -51,6 +51,86 @@
end
end

describe "#parent" do
let(:configuration) { Configuration.new }

shared_examples "for singular type" do
it "returns parent instance" do
expect(subject.configuration.parent).to eq(subject)
end

it "updates parent after assignment" do
subject.configuration = configuration
expect(configuration.parent).to eq(subject)
end
end

shared_examples "for array type" do
it "returns parent instance" do
expect(subject.configuration[0].parent).to eq(subject)
end

it "updates parent after assignment" do
subject.configuration = [configuration]
expect(configuration.parent).to eq(subject)
end
end

context "json" do
subject { custom_parent_class.new }

context "activerecord model parent" do
let(:custom_parent_class) do
build_custom_product_class do
attribute :configuration, Configuration.to_type
end
end

include_examples "for singular type"
end

context "store model parent" do
subject { custom_parent_class.new(configuration: Configuration.new) }

let(:custom_parent_class) do
Class.new do
include StoreModel::Model

attribute :configuration, Configuration.to_type
end
end

include_examples "for singular type"
end
end

context "array" do
subject { custom_parent_class.new(configuration: [Configuration.new]) }

context "activerecord model parent" do
let(:custom_parent_class) do
build_custom_product_class do
attribute :configuration, Configuration.to_array_type
end
end

include_examples "for array type"
end

context "store model parent" do
let(:custom_parent_class) do
Class.new do
include StoreModel::Model

attribute :configuration, Configuration.to_array_type
end
end

include_examples "for array type"
end
end
end

describe "==" do
let(:first_setting) { Configuration.new(color: "red") }

Expand Down

0 comments on commit dacdd3e

Please sign in to comment.