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

Read-only properties in embedded models not getting initialized #185

Open
jhecking opened this issue Dec 12, 2013 · 0 comments
Open

Read-only properties in embedded models not getting initialized #185

jhecking opened this issue Dec 12, 2013 · 0 comments

Comments

@jhecking
Copy link

When an embedded model gets initialized the directly_set_attributes option doesn't get passed through to the initializer call. Therefore read-only properties of the embedded model do not get set.

Here is a simple test case:

# encoding: utf-8
require "spec_helper"

class EmbeddedWithReadOnly
  include CouchRest::Model::Embeddable
  property :read_write, :read_only => false
  property :read_only, :read_only => true
end

class BaseModel < CouchRest::Model::Base
  property :embedded, :type => EmbeddedWithReadOnly
end

describe "initializing an embedded model" do
  it "should set a read-only property in an embedded model" do
    doc = BaseModel.build_from_database({type: "BaseModel", embedded: {type: "EmbeddedWithReadOnly", read_only: "foo", read_write: "bar"}})
    doc.embedded.read_write.should eq "bar"
    doc.embedded.read_only.should eq "foo"
  end
end

This test currently fails on master:

$ bundle exec rspec spec/functional/embeddable_with_read_only_spec.rb
F

Failures:

  1) initializing an embedded model should set a read-only property in an embedded model
     Failure/Error: doc.embedded.read_only.should eq "foo"

       expected "foo"
            got nil

       (compared using ==)
     # ./spec/functional/embeddable_with_read_only_spec.rb:18:in `block (2 levels) in <top (required)>'

Finished in 0.16174 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/functional/embeddable_with_read_only_spec.rb:15 # initializing an embedded model should set a read-only property in an embedded model

One possible fix is to check whether a property's type includes the CouchRest::Model::Embeddable module before building the property value - if it does, the :directly_set_attributes option should be passed into it's initializer:

diff --git a/lib/couchrest/model/typecast.rb b/lib/couchrest/model/typecast.rb
index ec5ac40..f32b2e0 100644
--- a/lib/couchrest/model/typecast.rb
+++ b/lib/couchrest/model/typecast.rb
@@ -15,6 +15,8 @@ module CouchRest
           type.couchrest_typecast(parent, property, value)
         elsif [String, Symbol, TrueClass, Integer, Float, BigDecimal, DateTime, Time, Date, Class].include?(type)
           send('typecast_to_'+type.to_s.downcase, value)
+        elsif type.ancestors.include?(CouchRest::Model::Embeddable)
+          property.build(value, directly_set_attributes: true)
         else
           property.build(value)
         end

I don't particularly like checking for the type of the property's class in this way so I hope there is a better way to fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant