Jsonapi-resources: foreign_key_on has_one clarification

Created on 19 Aug 2015  路  15Comments  路  Source: cerebris/jsonapi-resources

Hi,

I believe I'm using the new direction mechanism properly for has_one relationships, but I'm running into an issue where the foreign key is still being looked for on one of the models (in the current release and also on master):

class Master < ActiveRecord::Base
  has_one :detail
end

class Detail < ActiveRecord::Base
  belongs_to :master
end

class MasterResource < JSONAPI::Resource
  has_one :detail, foreign_key_on: :related
end

class DetailResource < JSONAPI::Resource
  has_one :master
end

Produces:

undefined method `detail_id' for #<Master:0x007f94f4a13bd8>

If this looks correct, I'll dig in and try to track this down. Thanks.

Most helpful comment

馃憤 that this still exists on 0.7.0. Supporting a proper belongs_to has_one relationship at the jsonapi-resources level would be more ideal than the current implementation.

All 15 comments

This is in fact correct, and works as expected on master as of Aug 19th. Local branch was slightly behind. Apologies for the cruft.

Just updated to 0.6.1 and this seems to be not working.

Here is what I have in my resource

module Api::V1
    class CountryResource < JSONAPI::Resource
        attributes :iso, :name, :threat_level, :updated_at

        relationship :overview, to: :one, foreign_key_on: :related
        relationship :institutions, to: :many
    end
end

and I get

Internal Server Error: undefined method `overview_id=' for class `Country'

What version where you previously using? Could you post the line number of the error?

Also, what do your models and tables look like?

I was using 0.5.9, so I did not have this working.

class Country < ActiveRecord::Base
    has_one :overview
end

class Overview < ActiveRecord::Base
    belongs_to :country, touch: true
end

and my I have country_id field in the overviews table, but I don't have overview_id in the countries table.

Here is the full stack trace of the error - https://gist.github.com/mupkoo/9df938d790fdc003e0a1

Adding the following method to my Country model does the trick

def overview_id=(_value)
   # TODO: Remove once it's fixed
end

@lgebhardt @bjubinville i believe this is an issue. the foreign_key_on: :related resource option works when looking up has_one related resources, but when saving those resources the code does not take this option into consideration (jsonapi-resources v0.7.0, jsonapi/resource.rb:211,797-799).

is this a missing feature or is it intended that saving a has_one active record association on a model/resource requires a patch like mupkoo's recommendation on the underlying model? or more completely:

def overview_id=(id)
  self.overview = Overview.find_by_id(id)
end

馃憤 that this still exists on 0.7.0. Supporting a proper belongs_to has_one relationship at the jsonapi-resources level would be more ideal than the current implementation.

IMHO, using has_one in place for belongs_to (as in Rails) is just wrong as it is very confusing for people used to working with Rails where has_one and belongs_to are opposite to each other. Introducing the foreign_key_on option makes things even more confusing. What is wrong with good old belongs_to?

@maprihoda belongs_to was added to the project in I believe the 0.8 release, though it has a deprecation warning. JSON API does not differentiate between a has_one and a belongs_to relationship, and it was decided that the resource declaration should try to reflect this. Therefore the preferred notation is to have the relationship describe the JSON API relationship with options to resolve to the rails model. The belongs_to method was added as a shortcut.

@lgebhardt what is the recommended way for a

has_one :user, through: :authentication

I added

def user_id=(_value)
end

but that feels wrong.

@fsmanuel I'm not sure I've tested a "has_one through" relationship. To work like the "has_many through" you should be able to declare the has_one :user, through: :authentication on the model and a has_one :user on the resource.

@lgebhardt that is what I'm doing and it works but I get the same error as above and have to define user_id=. Should we think about an option to prevent theforeign_key thing? I'm not so much into the internals of jsonapi-resources to say what that means. Not even sure where foreign_key is used.

This appears to still be an issue?

Nevermind, I should have just used foreign_key_on: :related. However, I think there's room to improve the exception description.

Was this page helpful?
0 / 5 - 0 ratings