Code Monkey home page Code Monkey logo

carrierwave-activerecord's People

Contributors

benders avatar richardkmichael avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

carrierwave-activerecord's Issues

Code gardening.

  • Move all TODOs to GH issues.
  • Remove all unnecessary comments.

StorageProvider spec improvements.

  • Re-factor to use implicit subject and review expectations.
  • We use mocks with .and_call_original because the methods being
    tested must execute the rest of the method to decorate the returned
    File. Alternately, we could use .and_return(@active_record_file_mock)
    to inject the correct type of file [build it from a Factory, because
    otherwise, the mocked file and the real File will eventually be out of
    sync.
  • Remove deep "implementation" testing, e.g. "calls #create!".
  • Instead of specing the return behavior of "store!" and
    "retrieve!", should we spec the return behaviour of only "retrieve!"
    and then specifiy that "store!" and "retrieve!" should return the same
    thing?
  • DRY URL spec with "shared_examples" / "it_behaves_like" / helper method module?
  • Use a named subject to fix the initialization of the StorageProvider under test.
  • Remove indirect and deep testing of File via uploader and should_receive (write it as a stub):

File.should_receive(:create!).with(file, identifier).and_call_original

File.should_receive(:fetch!).with(identifier).and_call_original

Implementation approach

Instead of writing a new engine using ActiveRecord, perhaps I should have just used the uploader module and extended it?

class ArticleUploader
  include CarrierWave::Mount

  def read_uploader ; end
  def write_uploader ; end

http://rubydoc.info/gems/carrierwave/CarrierWave/Mount

Return class

Should it return CarrierWave::SanitizedFile (like the file store)? The fog store returns a Fog::File instance.

Testing if a file is in the storage engine

What to do about .exists?? It can't be on the AR::Base instance. How to use the AR::Base.exists??

File metadata

What to do about .attributes?

A controller to serve files.

If we want http://app.com/files/my_file.txt to serve my_file.txt, we need a controller [to retrieve the file from the database and serve the content].

How do other non-filesystem storage engines present URLs to their files?

Confusion in Rails log regarding INSERTed data.

Although the data in the database is stored correctly and files can be stored and retrieved, there is confusion in the Rails log.

Binary data inserted for `string` type on column `file`
...
Binary data inserted for `string` type on column `identifier`

Remove RSpec.

  • Migrate rspec specification to minitest/spec.
  • Update .gemspec gem.test_files to execute the minitest suite.

Extract to a .gem?

lib/carrierwave/storage/active_record.rb

Add the engine to the engines variable in config.

Bump dependencies.

  • Remove :path => ... from the Gemfile
  • Relax ActiveRecord dependency, only need 3.2.x? Follow the version specified by CarrierWave.
  • Add explicit dependencies to .gemspec.

File#compute_url() does not consider nested models.

url = route_helpers.send(path_method_name, model)

Nested resources need a URL through their parent resource(s), and it must honour the retrieving request's path (in case they belong_to multiple models), ex. /path/via/gallery1/photo/1/file, /path/via/gallery/10/photo/1/file, /path/via/person/5/photo/1/file.

Approaches

  1. How can we obtain the request or URL from the controller when inside the model?
    Use Thread.current to store the request. Handled easily by the request_store gem. Then use the Rails router to re-parse the request.url? Or, put only the requisite parts of the parsed request into the Thread local instead of the entire request?
  2. Could we decorate the model using ActionView (like FormBuilder) on the way out of the controller?

Can @article.url call a Proc, which is executed with the binding of the view [controller?] to access the request?

def url
  Proc.new do
    # Access the request ... ?  We can capture the request using a Thread local.
  end.call
end

Same-named files overwrite each other.

CarrierWave overwrites an existing file when a new file with the same name is uploaded (even if handled by different uploaders), because store_dir defaults to /public/uploads.

The storage path may be configured per uploader by defining 'store_dir'. However, because we store in the database, this is not particularly helpful.

Create an install generator

Required setup:

  • Database table: we should generate a migration.
  • Rails route convention: /<model>/<model_id>/<mounted_attribute>, e.g. /person/1/avatar.

CarrierWave::Uploader::Store#filename should proxy to us.

There appears to be a bug in CarrierWave::Uploader::Store#filename -> @filename is nil, e.g. @filename is not being set by the cache code. Neither cache! nor retrieve_from_cache! are being called.

  • Review CarrierWave's Uploader spec re: Store#filename()

Workaround by adding a filename() method to your uploader:

class FooUploader
  def filename
    self.file.filename
  end
end

CarrierWave::Uploader should proxy the #filename() message to the file, as it does for other convenience methods. E.g. https://github.com/jnicklas/carrierwave/blob/master/lib/carrierwave/uploader/store.rb#L27 could do:

  @filename ||= file.filename if file.respond_to?(:filename)

Could we do something with Sprockets?

Probably not, since it would mean needing all the images (to precompile - can't compile on the fly without a filesystem? What about compiling to memcache?) ; and these are uploaded assets.

Configurable settings

  • table_name => default to 'carrier_wave_files'
  • by-pass the local cache (note that the cache sets @filename in the Uploader, should be fixed in CW)

Improve RSpec.

We don't use implicit subject everywhere, that's a smell.

References

Implicit subject with expect: http://stackoverflow.com/questions/12260534/using-implicit-subject-with-expect-in-rspec-2-11

Implicit subject as lambda: https://gist.github.com/timocratic/816049

Explicit subject as a test smell: http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/

Dynamic context with let: http://perevodik.net/en/posts/33/

Better RSpec techniques: http://betterspecs.org/

Discussion on command query separation, should_receive with and_return, and mocking on test doubles vs. partial mocking: rspec/rspec-expectations#190

The Transfer example, but should be atomic, and using a context seems strange:
https://gist.github.com/RStankov/1510673
http://blog.firsthand.ca/2011/12/example-using-rspec-double-mock-and.html

Re-work `identifier` to avoid a custom SHA1 identifier.

We compute a SHA1 as the identifier because we can't use a filename (.find_by_filename!()), because the filename won't necessarily be unique.

CarrierWave uses a before_save callback to invoke write_identifier: https://github.com/jnicklas/carrierwave/blob/master/lib/carrierwave/orm/activerecord.rb#L29

Because it's a before_save, the file has not been saved and we can't use the carrier_wave_files table ID as the identifier.

(What about giving the file to the storage engine, and receiving an identifier in return? E.g. Call store! and write_identifier in the before_save callback; or call write_identifier in an after_save callback?)

Or, use the filename as the identifier and change retrieval to use the associated model as well (e.g. identifier is effectively filename + model). However, this requires storing the model name and ID in the carrier_wave_files table (otherwise, we won't have any model information to join on).

File spec improvements.

Improve test coverage.

  • Setup rcov, then improve testing coverage.
  • Tests are needed for the private ActiveRecordFile class: attributes and table name.
  • Test improvements are needed, ensuring duck-typing of the CW::SanitizedFile methods.
  • Rspec implicit subject improvements

Add a <model>.<column>_filename method.

Add this to CarrierWave directly?

Seems that @article.image_filename would be helpful in views. Currently, we must do @article.image.filename. Not much difference .. but other convenience methods ._url`, etc. are provided.

Binary data provided for 'content_type'.

It appears to be a string, but Rails complains it's binary data.

  SQL (3.2ms)  INSERT INTO "articles" ("created_at", "file", "title", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Sun, 06 May 2012 10:49:26 UTC +00:00], ["file
", "twitter-setup-800-600.png"], ["title", "test 14"], ["updated_at", Sun, 06 May 2012 10:49:26 UTC +00:00]]
Binary data inserted for `string` type on column `content_type`
  SQL (0.6ms)  INSERT INTO "carrier_wave_files" ("content_type", "created_at", "data", "extension", "filename", "original_filename", "size", "updated_at") VALUES (?, 
?, ?, ?, ?, ?, ?, ?)  [["content_type", "image/png"], ["created_at", Sun, 06 May 2012 10:49:26 UTC +00:00], ["data", "\x89PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\
xC8\x00\x00\x00\x96\b\x06\x00\x00\x00\x9B\xDC\xC7\x19\x00\x00\x00\x04gAMA\x00\x00\xB1\x8F\v\xFCa\x05\x00\x00\x00\x01sRGB\x00\xAE\xCE\x1C\xE9\x00\x00\x00 cHRM\x00\x00z
&\x00\x00\x80\x84\x00\x00\xFA\x00\x00\x00\x80\xE8\x00\x00u0\x00\x00\xEA`\x00\x00:\x98\x00\x00\x17p\x9C\xBAQ<\x00\x00\x00\x06bKGD\x00\xFF\x00\xFF\x00\xFF\xA0\xBD\xA7\x
93\x00\x00\x00\tpHYs\x00\x00\v\x13\x00\x00\v\x13\x01\x00\x9A\x9C\x18\x00\x000\x17IDATx\xDA\xED\xBD\xDB\x8F$\xC9\x95\xE6\xF73\xBF{\xDC\xF3\x9Eu\xED.\x16\xBB\xC9n\xB2\x
C9\x19\r\xC9\xE1\x0E\xB1\x02\xB8\x02\xA1\x05\bi\x06|\x9A\x9D}\x1C\f\xF4$\xFD-\x12\xF6A\x8F\x1A\xBD\rV\x80\xB0\xC0\xCCR;Z\x8C0+\xED\x10\x04\xD9\x9C\xAEi\xB2\x97dW_\xAB
*\xAB2+#3\"#\xC2\xEF\xEEfz\x884+\xCF\xA8\xAC\xCC\xA8\xEEjfU\xB7\x7F@vW

Is this project dead?

No releases in years and years. Forks ahead with PR's that haven't been touched. Whats up?

Feedback on url() "decoration" of File: implementation and testing.

Rails 5 Compatibility

Version 0.1.0rc6 fails to bundle with rails 5 projects because of dependency conflicts. With those resolved, the tests fail to pass because of use of attr_accessible in lib/carrierwave-activerecord/storage/active_record_file.rb

Pull Request incoming, with a version bump so that separate branches and ruby gems can be maintained if you wish going forward. :)

Update the README.md

  • Use in a non-Rails environment
  • Wiki and example project links
  • Update cut-and-paste migration: remove content-type and other unused columns
  • Update file URL conventions and discussion

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.