Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    John Malone
    @Pro777
    @tobias_grasse_twitter The legacy app utilizes a lot of kruft that our new public API does not. By using the jsonapi-resource resource objects in the new vanilla rails frontend, we can just use the new policy objects we have created for our jsonapi.
    Dmitriy "Dima" Likhten
    @dlikhten

    Hi! I'm still on 0.9 and I was wondering if anyone can help out with this:

    I need to filter a relationship in my resource based on the context. For example:

    a person has many friends
    if I want to include person.friends.friends as an example I want to see the friends a person has and the friends they have that are mutual. Because this doesn't make sense in activerecord (this is request-specifc, not a special relationship) I would really need to make the scope records.friends.friends.where(is_friend: context[:person_id) (ignore how I build the actual where clause).

    Is this possible in 0.9?

    An alternative way to look at this:

    my PersonResource is scoped to only allow returning people who are self, or friends of whoever is in context[:person_id]. If I do include=friends.friends which is a PersonResource, the response is an error because one of the friends is not a mutual friend and thus the id is not found in the scope (and I don't want that record returned either).

    Dmitriy "Dima" Likhten
    @dlikhten

    To add a bit of context:

    Crash is in preload_included_fragments

    I assumed def records_for(association_name) would be where I can inject myself and make the necessary scoping... however that method is never invoked by the time the crash happens.

    The crash being Internal Server Error: key not found: 5735 (jsonapi/resource.rb:1354) because that key is out of scope for my resource.

    Dmitriy "Dima" Likhten
    @dlikhten
    Wondering if 0.10 solved this specific problem (I know there was a major re-do of the way relationships are queried)
    Josh Kramer
    @surjay

    Is there any way to customize relationship links? I know about the "custom_links" method/override for top-level resource links but I'm talking about the links within a relationship object. Specifically around turning a link into a JSON:API "link object". I'd like to be able to return a meta object along with the link href for things like counts. Something like this:

    "relationships": {
      "questions": {
        "links": {
          "related": {
            "href": "http://whatever.com/questions",
            "meta": {
              "count": 10
            }
          }
        },
        "data": []
      }
    }
    That or a better way to indicate counts for relationships as I've yet to find a good concensus on an approach.
    Tommy Russoniello
    @tommy-russoniello
    Josh Kramer
    @surjay

    Thanks, that might work. On a similar note, the JSON:API spec also suggests that the "relationship object" can also contain a meta object alongside "links" and "data". So something like this:

    "relationships": {
      "questions": {
        "links": {
          "related": "http://whatever.com/questions"
        },
        "data": [...],
        "meta": {
          "count": 10
        }
      }
    }

    Looking through the code and I don't see any easy way to populate/return meta at that level?

    Dmitriy "Dima" Likhten
    @dlikhten
    Idk if anyone experienced what I wrote above. Any ideas would be super helpful. Especially if someone already knows if 0.10 is the solution.
    Larry Gebhardt
    @lgebhardt
    @dlikhten I think v0.10 would make this easier, but you should be able to get this working in v0.9. Are you using subqueries?
    If you want to put together a simple test case I can try to help you get it working.
    Dmitriy "Dima" Likhten
    @dlikhten

    @lgebhardt subqueries? like you mean sq in where clauses or whatever? So basically the problem is that I override self.records in my resources to restrict what records can be seen based on my context (who is logged in). But on occasion a ?include=... includes a relationship that contains records that would otherwise be excluded by self.records. My question would be how to allow filtering of an association (including during included resources)? Typically I could do say record.association.where(...) but I don't know where in JR to put that code.

    If you need me to put together a mini-server on github to see the problem I can do that, but I was hoping that just knowing what methods exist could be a good start.

    Larry Gebhardt
    @lgebhardt
    @dlikhten In version v0.10 the way included resources are fetched should make this easier. I've got some appointments now, but I'll follow up in a few hours.
    Dmitriy "Dima" Likhten
    @dlikhten
    Thank you!
    Dmitriy "Dima" Likhten
    @dlikhten

    @lgebhardt sorry maybe I didn't quite get the meaning, what would be the right thing to override in 0.9 if you are aware of something that can be done. Currently my best plan is to remove the self.records restriction and take the serialized data and remove records from there in the processor which is definitely not the best performant way about it.

    And if 0.10 is definitely going to make things easier I will also look into it. Our only issue is some of our resources don't return db (activerecord) models which I still don't fully understand how to do in 0.10.

    Larry Gebhardt
    @lgebhardt
    FYI I mentioned in a side conversation with @dlikhten that I am working on v0.11. In that release I'd like to improve the process for non active record models and add back support for walking an eager loaded tree for the few cases where the v0.10 changes are creating problems.
    Dmitriy "Dima" Likhten
    @dlikhten
    The tl;dr of the convo
    • 0.10 solves my problem because self.records gets invoked during includes
    • 0.10 doesn't support non ActiveRecord models well, so I can't switch to it, hopeful for 0.11
    • To solve it in 0.9 I will be creating special models which join the logged in user with a nested relationship so I will have to query it directly (In the example of Hospital -> Patient -> Guardian -> Patient, I will need a HospitalGuardian with filters and HospitalPatient with filters, and won't be able to fetch the relationship directly, for now)
    reachire-smendola
    @reachire-smendola

    Hi all!
    I'm new to jsonapi-resources.
    I would like my API to have /my as an alias/shortcut to /users/{guid} where {guid} is the logged-in-user's id.
    Correspondingly, /my/someRelationship would be an alias for /users/{guid}/someRelationship
    e.g.
    GET /my/company
    GET /my/teams

    I did this:

    class MyResource < JSONAPI::Resource
      @_model_name = 'User'
      @_model_class = User
    
      has_one :company
      has_many :teams
    
      singleton singleton_key: lambda { |context|
        key = context[:current_user].try(:id)
        raise JSONAPI::Exceptions::RecordNotFound, nil if key.nil?
    
        key
      }
    end

    That works for GET /my, and it returns the JSON I would expect; the self link is /users/{guid}, which is what I actually would expect}
    companies and teams links are included in the JSON, and they also the non-shortcut URL's, which I consider "canonical"
    But as I said, I would like to be able to GET /my/company and /my/teams as well. That doesn' t work.
    I get:

    {
        "errors": [
            {
                "title": "Missing Parameter",
                "detail": "The required parameter, my_id, is missing.",
                "code": "106",
                "status": "400"
            }
        ]
    }

    Any suggestions?

    Larry Gebhardt
    @lgebhardt

    Instead of a new MyResource you could consider a route like /users/me. You could enforce this at the routes like:

    UUID_or_ME_regex ||= /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|([Mm][Ee])/
     jsonapi_resources :users, constraints: {:id => UUID_or_ME_regex}

    Then in the controller convert the Me to the logged in user

    ...
      before_action :convert_me_id
    
      def convert_me_id
        if params[:id] && params[:id].casecmp('me') == 0
          params[:id] = context[:current_user].id
        end
      end

    Your relationship routes would then be /users/me/company

    That has the advantage that there returned user is the same type as any other user. It also keeps it very simple

    You could also make Me and My both convert to the current user id so the route reads better /users/my/company. Still a bit "off" but not too bad in my mind
    reachire-smendola
    @reachire-smendola
    @lgebhardt, thank you for that, I do like it, and I will go with it. Nevertheless, if I would welcome suggestions on how to get /my to work as I wanted, more as a learning experience. But I will try, and probably use, /users/me .
    John Malone
    @Pro777
    I have a question about included relationships. I am expecting that the results here would return "data" -> []
    1 reply
    But I don't get any 'data' attribute at all with that relationship empty.
    Connor Handerhan
    @chanderhan
    Polymorphic belongs to
    Whoops that’s Send, not Search
    dguettler
    @dguettler_twitter
    Good Morning, does someone know if there is a way to filter included associations? E.g. a model may have many events which can be included when the model is requested. However the current user may not be allowed to see all events. Is there a way to apply a filter which events will be included.
    1 reply
    John Malone
    @Pro777
    Tobias Grasse
    @tobias_grasse_twitter
    @lgebhardt after upgrading to 0.10.x, I'm somewhat dumbfounded on how to serialize resources outside of a controller. Docs still mention serialize_to_hash, which is gone – impacts quite a few people, see cerebris/jsonapi-resources#1149 Would you or someone else be so kind to provide some guidance on the best approach? All routes I have tried (or others in that issue) have some unexpected downside or subtle errors.
    Benjamin Fleischer
    @bf4
    Same thing. I went through the code and gave up. Something to do with resource set, but what I tried failed
    Larry Gebhardt
    @lgebhardt
    Yes, v0.10 has made just serializing a resource a difficult task. I just wasn't aware of how many people were using the library that way. Restoring this functionality for v0.11 is a priority
    1 reply
    jameschenjav
    @jameschenjav
    I also got the issue with serialize_to_hash. I have to manually generate the data for one of our models. It's tricky to reference a table in another schema: class Bar < ApplicationRecord; self.table_name = 'foo.bar'; ...
    the query looks like SELECT foo.bar.id AS foo.bar_id, ...
    jameschenjav
    @jameschenjav
    there are so many Arel.sql("#{concat_table_field(resource_table_alias, cache_field[:name])} AS #{resource_table_alias}_#{cache_field[:name]}") in lib/jsonapi/active_relation_resource.rb. i guess you are trying to avoid name conflicts in different tables? its totally wrong way.
    in oracle, most identifier length can not exceed 30 characters, so your AS part can easily break the limit.
    jameschenjav
    @jameschenjav
    my current monkey patch is
        def self.uniq_table_alias_name(table_name, field_name)
          # `to_sym` to ensure the same `object_id` for each `table_name`
          # `to_s(36)` to keep it short: `('z'*13).to_i(36).to_s(16).size` => 17 => result.size <= 28
          "x#{table_name.to_sym.object_id.to_s(36)}_#{field_name.to_sym.object_id.to_s(36)}"
        end
    jameschenjav
    @jameschenjav
    in postgres and oracle, table name could be "FOO BAR", while the whitespace, double quote are part of the table name.
    Dmitriy "Dima" Likhten
    @dlikhten

    Hey, I couldn't find this in the docs anywhere, is there a recommended way to add a relationship to a resource (to-many) without having to override the whole relationship?

    Example:

    Hospital has many Patients

    If I want to add a new patient to a hospital:

    PUT /hospitals/123 {
       id: '123',
       type: 'hospital',
       relationships: {
         patients: {
            data: [{ id: '456', type: 'patient'}]
         }
       }
    }

    this will replace everything. :( Is there a framework recommended way to just say "add this one to the list"? (assume that going from either direction there's a lot of related records, say a many-to-many or whatever)

    My current workaround is a writable attribute addPatientId where when set will just add this relationship on the server via active record <<. But wondering if there is a better way.

    Connor Handerhan
    @chanderhan
    anyone have some pointers on authorization in 0.10?
    John Malone
    @Pro777
    @chanderhan Are you using any auth framework in particular?
    Connor Handerhan
    @chanderhan
    No - I like pundit but I am flexible
    John Malone
    @Pro777
    @chanderhan So we are using Pundit and were able to wire it into this lib by looking at this: https://github.com/togglepro/pundit-resources
    We are currently on v10.2.
    Jorge Luis
    @_hyphen_gitlab
    Hi, I'm trying to set a custom has many assoc that uses a instance dependent scope in the model but I'm running into an issue saying these scopes can not be preloaded, I've tried to disable the join by passing false to eager_load_on_include but it's still not working, any idea where I could look?
    Jorge Luis
    @_hyphen_gitlab
    nvm just noticed that eager_load_on_include does nothing, is there an alternative to prevent preloading?
    James Dixon
    @jamesdixon

    Hi everyone, new to this gem (and Rails) and trying to get a polymorphic relation setup. I have a User model that has a polymorphic association called profile, which can be of type Inspector or Buyer.

    I have the following:

    class Api::V1::Mobile::UserResource < JSONAPI::Resource
      immutable
      attributes :name, :email, :autologin
      has_one :profile, polymorphic: true
    end
    
    class Api::V1::Mobile::ProfileResource < JSONAPI::Resource
    end
    
    class Api::V1::Mobile::ProfilesController < Api::V1::Mobile::BaseController
    end

    However, whenever I make a call to my UsersController, I get the following error (truncated for brevity):

            "exception": "undefined method `collect' for nil:NilClass",
            "backtrace": [
              ".rvm/gems/ruby-2.6.5/gems/jsonapi-resources-0.10.2/lib/jsonapi/relationship.rb:77:in `resource_types'",

    When digging into relationship.rb it looks like it can't get resolve the polymorphic types, so I tried the following:

    class Api::V1::Mobile::UserResource < JSONAPI::Resource
      immutable
      attributes :name, :email, :autologin
      has_one :profile, polymorphic: true, polymorphic_types: ['inspector', 'buyer']
    end

    But alas, another error: Can't join 'User' to association named 'inspector'; perhaps you misspelled it?

    Maybe I'm just setting this up all wrong...would appreciate any input! Thanks in advance!

    James Dixon
    @jamesdixon
    @lgebhardt do you have any insight on this? Sorry, I've just about exhausted my options or I wouldn't ping you :)
    James Dixon
    @jamesdixon
    benebrice
    @benebrice
    Hi there!
    I was wondering how to use JR with non-CRUD method. I'm made a custom filter pretty useful and I really wanted to use the records methods (I'm on 0.9). This little trick does the job. It might help someone else.
    def my_method
      format_params_as('index', 'users')
      process_request
    end
    
    ##
    # Hack to use default jsonapi-resources behavior
    def format_params_as(method, resource)
      params['action'] = method # match the method
      old_resource = params["controller"].split('/').last
      params["controller"] = params["controller"].gsub(old_resource, resource) # Match the resource
    end