cerebris / jsonapi-resources

A resource-focused Rails library for developing JSON:API compliant servers.
http://jsonapi-resources.com
MIT License
2.32k stars 530 forks source link

Unable to clear relationship with PATCH data null (validation error) #812

Closed v-swamy closed 8 years ago

v-swamy commented 8 years ago

Hi -

Trying to learn the ins and outs of JSON API, so I'm working through Adolfo Builes e-book. My apologies if this is not the appropriate place but I'm not able to get a hold of the author and I'm at wits end!

Trying to clear a relationship with the below:

curl http://localhost:3000/loans/1/relationships/friend -X PATCH -H 
'Content-Type: application/vnd.api+json' --data-binary '{"data":null}' -i

and getting below error:

HTTP/1.1 422 Unprocessable Entity
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: application/vnd.api+json; charset=utf-8
Cache-Control: no-cache
X-Request-Id: 04cfcb69-0661-42b7-8523-0900c9bb4e20
X-Runtime: 0.009003
Transfer-Encoding: chunked

{"errors":[{"title":"must exist","detail":"friend - must exist","code":"100",
"source":{"pointer":"/data/relationships/friend"},"status":"422"}]}

But I have no validations on my Loan model:

class Loan < ActiveRecord::Base
  belongs_to :friend
  belongs_to :article
end

Here's the Friend model:

class Friend < ActiveRecord::Base
  validates :first_name, presence: true
  validates :email, presence: true
  validates :last_name, presence: true
  has_many :loans
end

Can anyone advise me why I'm getting the error? Thank you so much!

-Vik

lgebhardt commented 8 years ago

Those are validation errors. Which model has the title attribute on it?

lgebhardt commented 8 years ago

Also, there's a badge on the Readme for the Gitter chat room (https://gitter.im/cerebris/jsonapi-resources) which is a better area to ask questions like this. But this issue is also fine.

v-swamy commented 8 years ago

Oh thank you! I'll use that next time. Actually I have no model with a title attribute, I assumed that was part of the error object. Here's my schema file:

ActiveRecord::Schema.define(version: 20160823195558) do

  create_table "articles", force: :cascade do |t|
    t.string   "name"
    t.boolean  "available"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "friends", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.string   "email"
    t.string   "twitter"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "loans", force: :cascade do |t|
    t.text     "notes"
    t.integer  "friend_id"
    t.integer  "article_id"
    t.boolean  "returned"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["article_id"], name: "index_loans_on_article_id"
    t.index ["friend_id"], name: "index_loans_on_friend_id"
  end

end
lgebhardt commented 8 years ago

Sorry, I looked too quickly - title is part of the error. So the question remains why are you getting the validation error on friend. Can you null out the friend using the rails console without an error?

v-swamy commented 8 years ago

Good idea! I tried setting loan.friend to nil in the console (where loan is the loan mentioned above), but when I attempt to save the record, it is rolled back. How odd!

Subtletree commented 8 years ago

Had this same problem. Looks like its a new feature of rails 5, relationships are required by default.

http://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html

lgebhardt commented 8 years ago

@Subtletree Thanks for the link. I added a local test for setting nil and even with Rails 5 it's not failing in the test suite. If I set optional to false it will fail. So it seems more complicated than that. Maybe there's a setting we have made that I'm not seeing.

Subtletree commented 8 years ago

Have you got config.active_record.belongs_to_required_by_default = false set in your new_framework_defaults.rb initializer? Apparently if a rails app is upgraded to rails 5 this is set to false to maintain compatibility.

lgebhardt commented 8 years ago

@Subtletree Nothing in the test initialization, but if I explicitly set it to true the test does fail in rails 5. I added #817 to get the missing test in. Thanks again.

@v-swamy I'm going to close this issue since it doesn't look to be a problem in JR. Please reopen if you determine that it is indeed a JR issue.

v-swamy commented 8 years ago

Sorry for the late response - actually, setting config.active_record.belongs_to_required_by_default = false seemed to solve the issue for me. Thank you for looking into it!