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

Custom-Resource Classes: undefined method `[]=' for nil:NilClass in resource_builder:182 #79

Closed
toadle opened this issue Dec 3, 2015 · 10 comments
Assignees
Labels

Comments

@toadle
Copy link
Contributor

toadle commented Dec 3, 2015

Hey guys,

thanks for releasing 0.7 and fixing my last issue #69 . Today I set off to give this a shot, but still am not able to figure this out correctly. Perhaps I'm still doing something wrong:

I have a custom-resource Contentful::Category like this:

class Contentful::Category < Contentful::BaseEntry
  property :title
  property :slug
  property :image
  property :top
  property :subcategories
  property :featuredArticles
  property :seoText
  property :metaKeywords
  property :metaDescription
  property :metaRobots
end

where Contentful::BaseEntry looks like this:

class Contentful::BaseEntry
  include Draper::Decoratable
  include Contentful::Resource

All properties of Contentful::Category map to the attributes we have for our Content-Type.
I pass Contentful::Category to the Contentful::Client in the resource_mapping, when it's content-type's ID appears.

Now when calling client.entries('content_type' => <category content-type-id>) it gives me:

NoMethodError: undefined method `[]=' for nil:NilClass
from /Users/tim/.rvm/gems/ruby-2.2.2@hopla/bundler/gems/contentful.rb-bb9973d5dfbf/lib/contentful/resource_builder.rb:182:in `block (2 levels) in replace_children'

Which I can't really figure out why. Am I doing this right?

@dlitvakb
Copy link
Contributor

dlitvakb commented Dec 3, 2015

Hey @toadle,

Your BaseEntry class should inherit from Contentful::Entry instead of including Contentful::Resource, or include Contentful::Resource, Contentful::Resource::Fields and Contentful::Resource::SystemProperties

Please let me know if that fixes your problem

@dlitvakb dlitvakb self-assigned this Dec 3, 2015
@toadle
Copy link
Contributor Author

toadle commented Dec 3, 2015

@dlitvakb Thanks for getting back!

Of course, that works. That is what I've been doing all along.
But as you can also see in #69 : I'm basically just doing this to get FactoryGirl running in order to be able to have a test-suite for our project.

Therefore I was hoping the property :attribute definition would somehow get me to being able to use category.attribute and category.attribute= syntax.

But I suppose that is not possible, right?

@dlitvakb
Copy link
Contributor

dlitvakb commented Dec 3, 2015

@toadle Yes, as you say that works, the thing is that for parsing the api_response['fields'], Contentful::Resource::Fields must also be included, as that is where those are coerced into properties.

Contentful::Resource only provides a one-level deep coercion of attributes, therefore Contentful::Resource::Fields is required, or you need to redefine the method #fields_coercions

Hope that helps

@toadle
Copy link
Contributor Author

toadle commented Dec 3, 2015

@dlitvakb But still, when doing

class Contentful::Category < Contentful::BaseEntry
  property :title
  property :slug
  property :image
  property :top
  property :subcategories
  property :featured_articles
  property :cat_intro_head
  property :cat_introduction
  property :seo_text
  property :meta_keywords
  property :meta_description
  property :meta_robots

...
end

and having

class Contentful::BaseEntry < Contentful::Entry
...
end

Gives me

c = Contentful::Category.entries("sys.id" => "<some id>")
c.title
NoMethodError: undefined method `title' for #<Contentful::Array:0x007f8fd226a318>
from (pry):7:in `<main>'

Sorry, if I'm not getting this.

@danihodovic
Copy link

@danihodovic But still, when doing

You probably wanted to tag @dlitvakb 👯

@toadle
Copy link
Contributor Author

toadle commented Dec 3, 2015

@danihodovic Whoops, sorry.

@dlitvakb
Copy link
Contributor

dlitvakb commented Dec 3, 2015

Hey @toadle

Don't mess with @danihodovic he is training boxing! 👊

I'll look into it in more detail and try to reproduce it,

Can you paste me the JSON Preview for the Content Type you are using?

@toadle
Copy link
Contributor Author

toadle commented Dec 3, 2015

JSON-Preview:

{
  "name": "Kategorie",
  "description": "",
  "displayField": "title",
  "fields": [
    {
      "name": "Titel",
      "id": "title",
      "type": "Text",
      "required": true,
      "validations": []
    },
    {
      "name": "URL",
      "id": "slug",
      "type": "Symbol",
      "validations": []
    },
    {
      "name": "Bild",
      "id": "image",
      "type": "Link",
      "linkType": "Asset",
      "validations": []
    },
    {
      "name": "Feature-Artikel",
      "id": "featuredArticles",
      "type": "Array",
      "items": {
        "type": "Link",
        "linkType": "Entry",
        "validations": [
          {
            "linkContentType": [
              "5duKiNPsR20mgISegMYmwK"
            ]
          }
        ]
      },
      "validations": []
    },
    {
      "name": "Einleitungstext Headline",
      "id": "cat_intro_head",
      "type": "Symbol",
      "validations": []
    },
    {
      "name": "Einleitungstext",
      "id": "cat_introduction",
      "type": "Text",
      "required": false,
      "validations": []
    },
    {
      "name": "Unterkategorie",
      "id": "subcategories",
      "type": "Array",
      "items": {
        "type": "Link",
        "linkType": "Entry",
        "validations": [
          {
            "linkContentType": [
              "2vg0mzjdfm4myqIQyqiW0M"
            ]
          }
        ]
      },
      "validations": []
    },
    {
      "name": "Top-Kategorie",
      "id": "top",
      "type": "Boolean",
      "validations": []
    },
    {
      "name": "Homepage-Kategorie",
      "id": "homepage",
      "type": "Boolean",
      "validations": [],
      "disabled": true
    },
    {
      "name": "SEO-Text",
      "id": "seoText",
      "type": "Text",
      "validations": []
    },
    {
      "name": "META-Keywords",
      "id": "metaKeywords",
      "type": "Symbol",
      "validations": []
    },
    {
      "name": "META-Description",
      "id": "metaDescription",
      "type": "Symbol"
    },
    {
      "name": "META-Canonical",
      "id": "metaCanonical",
      "type": "Symbol",
      "validations": [],
      "disabled": true
    },
    {
      "name": "META-Robots",
      "id": "metaRobots",
      "type": "Symbol",
      "validations": [
        {
          "in": [
            "index/follow",
            "noindex/nofollow",
            "noindex/follow",
            "index/nofollow"
          ]
        }
      ]
    }
  ],
  "sys": {
    "id": "2vg0mzjdfm4myqIQyqiW0M",
    "type": "ContentType",
    "createdAt": "2015-09-18T13:20:06.669Z",
    "createdBy": {
      "sys": {
        "type": "Link",
        "linkType": "User",
        "id": "3uRyZjPepZB5ZKOihyqgne"
      }
    },
    "space": {
      "sys": {
        "type": "Link",
        "linkType": "Space",
        "id": "01e3d4iatuxi"
      }
    },
    "firstPublishedAt": "2015-09-18T13:20:07.113Z",
    "publishedCounter": 14,
    "publishedAt": "2015-11-10T14:17:43.162Z",
    "publishedBy": {
      "sys": {
        "type": "Link",
        "linkType": "User",
        "id": "3uRyZjPepZB5ZKOihyqgne"
      }
    },
    "publishedVersion": 27,
    "version": 28,
    "updatedAt": "2015-11-10T14:17:43.183Z",
    "updatedBy": {
      "sys": {
        "type": "Link",
        "linkType": "User",
        "id": "3uRyZjPepZB5ZKOihyqgne"
      }
    }
  }
}

@dlitvakb
Copy link
Contributor

dlitvakb commented Dec 7, 2015

@toadle sorry for the delay on the response, I was sick on Friday.

I'll keep looking onto this, thanks for providing the JSON

@dlitvakb
Copy link
Contributor

dlitvakb commented Dec 7, 2015

Hey @toadle,

I found a solution,

You can currently use this workaround while I add it into the core library

The following code is a very simple local test I used for making your code work.

#!/usr/bin/env ruby

require 'contentful'

class Kategorie < Contentful::Entry
  property :title
  property :slug
  property :image
  property :top
  property :subcategories
  property :featured_articles
  property :cat_intro_head
  property :cat_introduction
  property :seo_text
  property :meta_keywords
  property :meta_description
  property :meta_robots

  def initialize(*)
    super

    client.content_type(content_type['sys']['id']).fields.each do |f|
      define_singleton_method Contentful::Support.snakify(f.id).to_sym do |wanted_locale = default_locale|
        fields(wanted_locale)[f.id.to_sym]
      end
    end
  end
end

def assert(expectee, expected)
  raise unless expected == expectee
end

def main
  client = Contentful::Client.new(
    access_token: 'd230af21290965e573830bcddadbac0cd7dc13b926fda7394981d610c7f61ee0',
    space: 'g2b4ltw00meh',
    dynamic_entries: :auto,
    entry_mapping: {
      'kategorie' => Kategorie
    }
  )

  entry = client.entries.first

  assert(entry.is_a?(Kategorie), true)

  assert(entry.title, "Some Title")
  assert(entry.slug, "/asda.html")
  assert(entry.featuredArticles.first.is_a?(Contentful::Link), true)
  assert(entry.top, true)
end

main

Currently it relies on defining the properties from the fields values, as DynamicEntry only defines that upon creation and it's static.

Solution will move the code I'm using for the workaround (which is a slightly modified version of the one in the Contentful::DynamicEntry::create static method) into initialize, then, the workaround code could be removed.

Please let me know if this helps

cc @grncdr

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

No branches or pull requests

3 participants