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

Read map functions from separate .js files #158

Open
azul opened this issue Jan 1, 2013 · 1 comment
Open

Read map functions from separate .js files #158

azul opened this issue Jan 1, 2013 · 1 comment

Comments

@azul
Copy link
Contributor

azul commented Jan 1, 2013

I put all the map functions in .js files in a separate folder and i am currently using this to load them:

  class CouchRest::Model::Designs::DesignMapper
    def load_views(dir)
      Dir.glob("#{dir}/*.js") do |js|
        name = File.basename(js, '.js')
        file = File.open(js, 'r')
        view name.to_sym, :map => file.read
      end
    end
  end

It allows for a much cleaner model file without text blocks and js files get syntax highlighting. I am thinking about adding coffeescrip and making the js files unit testable with jasmine and the like.

Wondering if this would be a feature you'd like to see in couchrest_model or i should put it into a separate project.

@samlown
Copy link
Member

samlown commented Jan 17, 2013

Hi. This is a subject I've been thinking about a lot, but never arrived at a decent conclusion. While it is nice to not have Javascript in the models, there are some interesting use cases where it does make sense. For example, using variables inside the javascript or re-using blocks of javascript between multiple maps.

Recently, I've actually started using Rails Concerns to separate the designs. This works quite well! For example:

    class Invoice < CouchRest::Model::Base
      include Statistics
    end

    module Invoice::Statistics
      extend ActiveSupport::Concern
      included do
        design :stats do
           view :by_something_useful, :map => <<-MAP, :reduce => :sum
              function(d) {
                if (d['type'] == 'Invoice') {
                  emit(something, 1);
                }
              }
           MAP
        end
    end

Having said that, there are clearly benefits to separate files, especially if you want to do some kind of unit tests. The hardest part is deciding on the convention to use. I'd suggest trying to load the files automatically based on path, for example in a Rails project:

 /app/model/designs/invoice/views/by_something_useful/map.js

If you wanted to namespace the Design documents you can add another directory:

 /app/model/designs/invoice/stats/views/by_something_useful/map.js

And of course your reduce method would need to be defined in the same way:

 /app/model/designs/invoice/views/by_something_useful/reduce.js

And if you can't be bothered with lots of paths:

/app/model/designs/invoice.js  # => _design/Invoice
/app/model/designs/invoice/stats.js  # => _design/Invoice_stats

Shouldn't be too difficult to implement something like that if you're up for it!

Cheers, sam

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

2 participants