Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveStorage and Mongo #31408

Closed
aledalgrande opened this issue Dec 12, 2017 · 15 comments
Closed

ActiveStorage and Mongo #31408

aledalgrande opened this issue Dec 12, 2017 · 15 comments

Comments

@aledalgrande
Copy link
Contributor

aledalgrande commented Dec 12, 2017

Steps to reproduce

This is a possible feature request. I just installed Rails 5.2.0 beta2 and created a project with the -O option because I want to use Mongo instead of a relational database. What I noticed is that ActiveStorage, which I wanted to try out, was also disabled. I just saw that the gem is depending on ActiveRecord exclusively.

Expected behavior

Create a project with -O but not with --skip-active-storage and have ActiveStorage available, while ActiveRecord is disabled.

Actual behavior

ActiveStorage is not available.

System configuration

Rails version: 5.2.0.beta2

Ruby version: ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16]

@rafaelfranca
Copy link
Member

Active Storage only support Active Record and we have no plans to work in different ORMs support. Of course if you are willing to make Active Storage working with Mongo feel free to send PRs.

@aledalgrande
Copy link
Contributor Author

Gotcha thanks @rafaelfranca

@rgaufman
Copy link

Has this changed at all?

I thought ActiveStorage would work with anything that uses ActiveModel, a bit like ActiveJob works with Sidekiq and others. But trying to use it immediately throws an active record migrations exception. Maybe it should be called ActiveRecordStorage as it is currently implemented 🙈

@georgeclaghorn
Copy link
Contributor

No.

@HLFH
Copy link

HLFH commented Oct 26, 2018

Since some of us may use Rails with the Ruby ODM framework for MongoDB mongoid, I would advise them to use the gems shrine with nextcloud.

@zedtux
Copy link
Contributor

zedtux commented Jan 13, 2019

@rafaelfranca Why is Active Storage supporting only Active Record and why don'y you have any plan to work with other ORMs support?
What is the reason behind as I fully agree with @rgaufman?

Please avoid the "No." answer like @georgeclaghorn which is really useless

@sikachu
Copy link
Member

sikachu commented Jan 13, 2019

I understand the frustration.

However, from what I see, I think none of us are actually use ODM in our companies. Merging code into core comes with a maintenance burden. With us not really "eating our own dog food", I don't think it's a good idea for Active Storage to have ODM support as we probably do not know what we are doing (compared to, say, use job and queue with Resque backend)

However, I think we probably are open if anyone want to make a activestorage-mongoid or similar adapter, same as how Rails support multiple database backend. If someone would like to give a shot on making a gem, and maybe submit a few patches to make integration point easier, I really see no reason why core team wouldn't be okay with that.

@zedtux
Copy link
Contributor

zedtux commented Jan 14, 2019

That sounds good ! Thank you @sikachu.

@rafaelfranca
Copy link
Member

@sikachu said everything. We are happy to have a multi-adapter support for Active Storage but we are not going to do the work for it. If there is interest from a mongoid adapter I'd suggest people to try to implement it with the current API and as soon a new adapter takes traction we can change the framework to make new adapters easier. The reason for that is to avoid building an extension API that nobody will use.

@zedtux
Copy link
Contributor

zedtux commented Jan 15, 2019

Thank you @rafaelfranca for the additional details

@rogerprz
Copy link

Any updates for ActiveStorage and mongoid?

@jafuentest
Copy link

What would be the best approach to do this? I think I can get my company to support the development of a mongoid adapter for active storage, I'm just not sure which would be the best way to proceed

@leoarnold
Copy link

@jafuentest In order to do this, one would need to disentangle ActiveStorage from ActiveRecord.

If we take for example a look at ActiveStorage::Blob, we find that it uses ActiveRecord::Store

store :metadata, accessors: [ :analyzed, :identified ], coder: ActiveRecord::Coders::JSON

and ActiveRecord::Store relies on ActiveRecord::AttributeMethods::Serialization::ClassMethods#serialize:

serialize store_attribute, IndifferentCoder.new(store_attribute, options[:coder])

which in turn uses ActiveRecord::AttributeDecorators and ActiveRecord::ModelSchema::ClassMethods#reload_schema_from_cache.

Therefore, ActiveRecord::Store cannot simply be included in a kind of "MongoidAdapter". One would have to find a different solution here. Note that the analyzers and variants make use of the metadata field as well.

Furthermore ActiveStorage::Attached::Model and ActiveStorage::Attachment use transaction callbacks like after_create_commit which are (AFAIK at time of writing) not available in Mongoid (but MongoDB 4 and the mongo driver at least support transactions).

And then, there are ActiveRecord::Reflections which also seem to be closely coupled to AR

reflection = ActiveRecord::Reflection.create(
:has_many_attached,
name,
nil,
{ dependent: dependent, service_name: service },
self
)
ActiveRecord::Reflection.add_attachment_reflection(self, name, reflection)

If we can find suitable abstractions and indirections to decouple ActiveStorage from ActiveRecord, the rest seems pretty much a straightforward analogy to ActiveJob's queue adapter system:

module QueueAdapters
extend ActiveSupport::Autoload
autoload :AsyncAdapter
autoload :InlineAdapter
autoload :BackburnerAdapter
autoload :DelayedJobAdapter
autoload :QueAdapter
autoload :QueueClassicAdapter
autoload :ResqueAdapter
autoload :SidekiqAdapter
autoload :SneakersAdapter
autoload :SuckerPunchAdapter
autoload :TestAdapter
ADAPTER = "Adapter"
private_constant :ADAPTER
class << self
# Returns adapter for specified name.
#
# ActiveJob::QueueAdapters.lookup(:sidekiq)
# # => ActiveJob::QueueAdapters::SidekiqAdapter
def lookup(name)
const_get(name.to_s.camelize << ADAPTER)
end
end
end
end

@ughstudios
Copy link

Has anything changed since the last posting on this thread?

@leoarnold
Copy link

@BDoom Yes, another round of futile discussion: #42901

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests