rmosolgo / graphql-ruby

Ruby implementation of GraphQL
http://graphql-ruby.org
MIT License
5.38k stars 1.39k forks source link

Active Storage support #1777

Closed KevinColemanInc closed 5 years ago

KevinColemanInc commented 6 years ago
"exception": "#<RuntimeError: No connection implementation to wrap ActiveStorage::Attached::Many (#<ActiveStorage::Attached::Many:0x00007fceb5e6d5f8>)>"

I am running 1.7.14, so maybe 1.8 supports this already.

rmosolgo commented 6 years ago

No, not supported by graphql-ruby yet! Actually, I haven't even looked at ActiveStorage yet 🙈

KevinColemanInc commented 6 years ago

For other people seeing this, I am converting it to an array type as a temporary work around.

casiodk commented 6 years ago

It would be very nice to have active storage support!

t2 commented 6 years ago

@kevincolemaninc can you elaborate a bit? Maybe a snippet of your type definition?

KevinColemanInc commented 6 years ago

@t2

you can call .to_a on your active_storage models which converts it to an array which graphql can process. Unfortunately, its not treated like a connection so you will need to do your own pagination.

Sanchezdav commented 5 years ago

I did something like this to get the image url, is this ok?

module Types
  class PostType < Types::BaseObject
    field :id, ID, null: false
    field :title, String, null: false
    field :content, String, null: false
    field :image_url, String, null: true

    def image_url
      attachment = Post.find(id)&.image_attachment
      return if attachment.nil?

      Rails.application.routes.url_helpers.rails_blob_url(attachment, only_path: true)
    end
  end
end
KevinColemanInc commented 5 years ago

@Sanchezdav

This would cause an N+2 for each type. Rails will do:

If speed isn't important or you're not loading very many post types, your solution might be tolerable.

mengqing commented 5 years ago

As far I can see, ActiveStorage::Attached::Many can simply be treated as ActiveRecord::Relation, and all you need to do is just register ActiveStorage::Attached::Many to GraphQL::Relay::RelationConnection as the custom connection implementation.

GraphQL::Relay::BaseConnection.register_connection_implementation(
  ActiveStorage::Attached::Many,
  GraphQL::Relay::RelationConnection
)

class User < ApplicationRecord
  has_many_attached :images
end

class ActiveStorageAttachment < GraphQL::Schema::Object
  field :id, ID, null: false
end

class UserType < GraphQL::Schema::Object
  field :images, ActiveStorageAttachment.connection_type, null: false
end

I haven't fully tested this but being using this method for some time now. I can create a PR if needed

To solve the N+1 issue, just use the batch gem.

rmosolgo commented 5 years ago

Thanks for sharing your solution! If someone wants to contribute first-class support for ActiveStorage, I'm happy to review a PR for it.

joardar-aditya commented 4 years ago

``

I did something like this to get the image url, is this ok?

module Types
  class PostType < Types::BaseObject
    field :id, ID, null: false
    field :title, String, null: false
    field :content, String, null: false
    field :image_url, String, null: true

    def image_url
      attachment = Post.find(id)&.image_attachment
      return if attachment.nil?

      Rails.application.routes.url_helpers.rails_blob_url(attachment, only_path: true)
    end
  end
end

This Looks like a quick solution although use 'object' to access the current object rather than query on id and for solving N+1 problem use batch gem