Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Marvin Arnold
    @marvinmarnold
    I would like to define an attribute for a resource. But the returned value should be a function of a query parameter. Meaning the return value of the attribute should vary based on an optional query param. Is this possible?
    Dave Willett
    @dwillett
    We are spiking on an update to Rails 6.1 RC2 and noticed that the ActionController::ForceSSL class has been removed. This throws an error from the gem here: https://github.com/cerebris/jsonapi-resources/blob/master/lib/jsonapi/resource_controller_metal.rb#L8 . I don't see anything active to get ahead of that removal
    Larry Gebhardt
    @lgebhardt
    @marvinmarnold The context is available in the resource. So you could set a value in the context in the controller and reference that in the getter for the attribute.
    John Malone
    @Pro777
    What is the current state of Etags, cache-control headers, and 304 Not Modified for jsonapi-resources?
    I saw mention of this in existing Github issues and also on this channel.
    Josh Justice
    @CodingItWrong
    @dwillett I just saw the same error with ForceSSL. I'll open an issue now.
    benebrice
    @benebrice

    Hi guys!
    I'm migrating from 0.9 to 0.10 and I'm switching from records_for to apply_join and I've some issues with my id key (which is uuid and not id).

    It seems that JSONAPI::PrimaryResourceIdTree (on JSONAPI::Processor#find_resource_id_tree still use id instead of uuid which leads to an error on JSONAPI::ResourceSet#populate! with @resource_klasses[resource_klass][resource.id] where resource.id is a correct uuid but key of the hash resulting of find_resource_id_tree is still id (and not uuid).

    Does anyone else have had this issue before?

    Thank you in advance !

    benebrice
    @benebrice
    @lgebhardt I've had a similar issue with 0.9 where I've added a patch for association has_one with different foreign key (foreign_key_type_changed). I'm not confident enough with 0.10 to propose a fix yet.
    Adam Robertson
    @arcreative
    Hi all, been a while!
    Not sure if there have been advancements with a particular use case I have... namely one where I keep finding that I need access to the relation used for a find operation in a processor
    so for instance, if i have some records that are being found and i want to append some metadata onto them in an efficient way, I still don't seem to have any way to grab the relation so I know what to provide the data for. Is there any new way to do this?
    In 0.9.x I made a hacky method that worked pretty well by emulating some resource behavior for filtering and the like, but 0.10.x made those methods protected, so it seems like i need to reinvent the wheel again
    Adam Robertson
    @arcreative
    This works if I put it in my main processor class, but obviously it's not a a great solution since it's leaning on internals, and is probably an incomplete implementation
      def get_relation
        verified_filters = resource_klass.verify_filters(params[:filters], context)
        resource_klass._model_class.where(verified_filters)
      end
    
      def get_sorted_relation
        sort_criteria = params.fetch(:sort_criteria, [])
        order_options = resource_klass.send(:construct_order_options, sort_criteria)
        resource_klass.send(:sort_records, get_relation, order_options, context)
      end
    
      def get_paginated_relation
        paginator = params[:paginator]
        get_sorted_relation.limit(paginator.limit).offset(paginator.offset)
      end
    Adam Robertson
    @arcreative
    Also, I just discovered after spelunking for a few that maybe the sort method is better for most use cases than overriding self.apply_sort--is there a reason this isn't documented?
    def self.sortable_fields(_context)
      super + %i[category_natural]
    end
    
    sort :category_natural, apply: -> (records, direction, _context) {
      categories_mapped = Account::ACCOUNT_CATEGORIES.map(&Account.connection.method(:quote))
      subcategories_mapped = Account::ACCOUNT_SUBCATEGORIES.map(&Account.connection.method(:quote))
      records
        .order("COALESCE(array_position(array[#{categories_mapped.join(',')   }], accounts.account_category::text   ), 100) #{direction}")
        .order("COALESCE(array_position(array[#{subcategories_mapped.join(',')}], accounts.account_subcategory::text), 100) #{direction}")
    }
    also, it seems that if I've called sort, it should automatically add that to the sorted fields hash instead of having to add it explicitly. That's just QoL though.
    Dmitriy "Dima" Likhten
    @dlikhten

    Hey, I have a very odd need... I need to be able to commit a record to the database during say an update, and even if the update overall fails I need that record saved. Basically I need my own manual transaction control in a situation.

    A good example: I need to create a payment record, commit it, then do a bunch of updates with db locks to ensure no double payment, then commit an update to that payment record that it completed.

    Is there anything that allows for that inside the resource?

    My current plan is a custom method in my controller and control the transaction manually.

    benebrice
    @benebrice
    Override _save method on the model?
    (Working on version 0.9 for me)
    On the resource*
    Dmitriy "Dima" Likhten
    @dlikhten
    you mean in the resource? Or is the resource not managing transactions and I am just making something up?
    benebrice
    @benebrice
    Yes in the resource. Take a look at this method on the source. You can call super and handle error the way you want.
    Dmitriy "Dima" Likhten
    @dlikhten
    I looked into it. _save doesn't have transactions. The transaction is set up in the operation_dispatcher.rb
    benebrice
    @benebrice
    In that case, I think what you ask is a bit tricky without implementing your own dispatcher. 😕
    Dmitriy "Dima" Likhten
    @dlikhten
    :( yeah its what i thought. I'll probably make a custom method and just invoke the serialized for the response.
    Adam Robertson
    @arcreative
    @dlikhten Not sure if it's right for your use case, but you can use a thread
    Thread.new do
      ActiveRecord::Base.connection_pool.with_connection do
        ...
      end
    end
    Dmitriy "Dima" Likhten
    @dlikhten
    @arcreative I haven't considered that option. Even if I don't end up using this, it is a good tool for the toolbox. Thanks!
    Josh Justice
    @CodingItWrong
    I'm pretty sure this is an issue to open, but asking here first to follow the issue template.
    Running JR on Ruby 3.0.0, when I attempt to use a sort, I get the error "undefined method `unescape' for URI:Module". I believe that method has been removed in Ruby 3.0.0 so it seems like this is an issue that'd need to be fixed in JR. Does anyone know of another workaround?
    Benjamin Fleischer
    @bf4
    @CodingItWrong if you' on 0.9.0 that's a known issue with a PR ( cerebris/jsonapi-resources#1340 ) cc @lgebhardt
    Artur
    @artur79
    Hi, I'd like to apply filter for a relation using >= (greater than), for equal I'v got, how for gt ?
    parameter name: 'filter[user.grade.level]', in: :query, type: :integer, required: false
    Artur
    @artur79
    I'v also tried to set type to string and pass 4+ for level and seems that it's cut to "4 "
    benebrice
    @benebrice
    Did you try to use apply_filter method on your resource?
    Artur
    @artur79
    parameter name: 'filter[user.grade.level][ge]', in: :query, type: :integer, required: false
    This message was deleted
    Artur
    @artur79
    trying approach like below, not sure though is it a standard one
    
      filter :'user.grade.level', apply: ->(records, value, _options) do
        scope = records.joins(user: :grade)
        level = value[0]
    
        if level.is_a?(Hash) && lge = level['ge']
          scope.where('grades.level >= ?', lge.to_i)
        else
          scope.where(grades: { level: level.to_i })
        end
      end
    and got error
    {"exception":"undefined method `to_i' for \u003cActionController::Parameters {\"ge\"=\u003e\"5\"} permitted: false
    Is it a problem with parameter definition ? Or I need to permit sth in controller
    Artur
    @artur79
    apply_filter method is mentioned to be deprecated https://jsonapi-resources.com/v0.10/guide/resources.html#Applying-Filters
    benebrice
    @benebrice
    It's deprecated because you're using 0.10 😉
    Pay attention to \u003E (which is unicode character). ge should be enough to know that it's greater than. Then pass only number value. This is your error I would say.
    Artur
    @artur79
    @benebrice not sure what you mean with ge, that's what I pass like this in spec: let!(:'filter[user.grade.level][ge]') { 5 }
    benebrice
    @benebrice
    Error shows {\"ge\"=\u003e\"5\"} \u003e is a unicode character. Check your request. I would say you've passed filter[user.grade.level] = { ge: '>5'}
    Artur
    @artur79

    has some bugs in the code and was trying to pass hash in the spec as param value, here's final working version

      filter :'user.grade.level', apply: ->(records, value, _options) do
        scope = records.joins(user: :grade)
        level = value[0]
    
        if level.respond_to?(:to_h) && level.has_key?('ge')
          scope.where('grades.level >= ?', level['ge'].to_i)
        else
          scope.where(grades: { level: level.to_i })
        end
      end

    and in spec param is like let(:'filter[user.grade.level]') { 4 } or let(:'filter[user.grade.level][ge]') { 5 }

    btw, need to mention that even if params are specified like

    parameter name: 'filter[user.grade.level]', in: :query, type: :integer, required: false
    parameter name: 'filter[user.grade.level][ge]', in: :query, type: :integer, required: false

    a String is passed (e.g "5") not Integer

    Larry Gebhardt
    @lgebhardt
    Could I get a few eyes on cerebris/jsonapi-resources#1314 Specifically I'm looking for opinions on the hashing algorithm used for computing the cache keys (when the resource has changed / cache is invalidated). I think the switch to use to_f for timestamps makes sense, but would welcome other ideas.