Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial proof of concept for multi-lingual Spree backend

  • Loading branch information...
commit cbd3f7cb7503cf64ed4f4b145ff12fdb364108e7 0 parents
jipiboily authored
11 .gitignore
@@ -0,0 +1,11 @@
+\#*
+*~
+.#*
+.DS_Store
+.idea
+.project
+tmp
+nbproject
+*.swp
+spec/dummy
+.rvmrc
1  .rspec
@@ -0,0 +1 @@
+--colour
13 Gemfile
@@ -0,0 +1,13 @@
+source 'http://rubygems.org'
+
+group :test do
+ gem 'ffaker'
+end
+
+if RUBY_VERSION < "1.9"
+ gem "ruby-debug"
+else
+ gem "ruby-debug19"
+end
+
+gemspec
231 Gemfile.lock
@@ -0,0 +1,231 @@
+PATH
+ remote: .
+ specs:
+ spree_multi_lingual (0.1.0.alpha1)
+ coffee-rails
+ globalize3 (~> 0.2.0.beta8)
+ i18n
+ sass
+ spree_core (~> 1.0.0)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ actionmailer (3.1.3)
+ actionpack (= 3.1.3)
+ mail (~> 2.3.0)
+ actionpack (3.1.3)
+ activemodel (= 3.1.3)
+ activesupport (= 3.1.3)
+ builder (~> 3.0.0)
+ erubis (~> 2.7.0)
+ i18n (~> 0.6)
+ rack (~> 1.3.5)
+ rack-cache (~> 1.1)
+ rack-mount (~> 0.8.2)
+ rack-test (~> 0.6.1)
+ sprockets (~> 2.0.3)
+ active_utils (1.0.3)
+ activesupport (>= 2.3.11)
+ i18n
+ activemerchant (1.20.1)
+ active_utils (>= 1.0.1)
+ activesupport (>= 2.3.11)
+ braintree (>= 2.0.0)
+ builder (>= 2.0.0)
+ i18n
+ json (>= 1.5.1)
+ money (<= 3.7.1)
+ activemodel (3.1.3)
+ activesupport (= 3.1.3)
+ builder (~> 3.0.0)
+ i18n (~> 0.6)
+ activerecord (3.1.3)
+ activemodel (= 3.1.3)
+ activesupport (= 3.1.3)
+ arel (~> 2.2.1)
+ tzinfo (~> 0.3.29)
+ activeresource (3.1.3)
+ activemodel (= 3.1.3)
+ activesupport (= 3.1.3)
+ activesupport (3.1.3)
+ multi_json (~> 1.0)
+ acts_as_list (0.1.4)
+ archive-tar-minitar (0.5.2)
+ arel (2.2.1)
+ braintree (2.13.4)
+ builder (>= 2.0.0)
+ builder (3.0.0)
+ capybara (1.0.1)
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ selenium-webdriver (~> 2.0)
+ xpath (~> 0.1.4)
+ childprocess (0.3.1)
+ ffi (~> 1.0.6)
+ cocaine (0.2.1)
+ coffee-rails (3.1.1)
+ coffee-script (>= 2.2.0)
+ railties (~> 3.1.0)
+ coffee-script (2.2.0)
+ coffee-script-source
+ execjs
+ coffee-script-source (1.2.0)
+ columnize (0.3.6)
+ deface (0.7.2)
+ nokogiri (~> 1.5.0)
+ rails (>= 3.0.9)
+ diff-lcs (1.1.3)
+ erubis (2.7.0)
+ execjs (1.3.0)
+ multi_json (~> 1.0)
+ factory_girl (2.5.2)
+ activesupport (>= 2.3.9)
+ ffaker (1.12.1)
+ ffi (1.0.11)
+ globalize3 (0.2.0.beta8)
+ activemodel (>= 3.0.0)
+ activerecord (>= 3.0.0)
+ paper_trail (~> 2)
+ highline (1.6.8)
+ hike (1.2.1)
+ i18n (0.6.0)
+ jquery-rails (1.0.19)
+ railties (~> 3.0)
+ thor (~> 0.14)
+ json (1.6.5)
+ kaminari (0.13.0)
+ actionpack (>= 3.0.0)
+ activesupport (>= 3.0.0)
+ railties (>= 3.0.0)
+ linecache19 (0.5.12)
+ ruby_core_source (>= 0.1.4)
+ mail (2.3.0)
+ i18n (>= 0.4.0)
+ mime-types (~> 1.16)
+ treetop (~> 1.4.8)
+ meta_search (1.1.1)
+ actionpack (~> 3.1.0)
+ activerecord (~> 3.1.0)
+ activesupport (~> 3.1.0)
+ polyamorous (~> 0.5.0)
+ mime-types (1.17.2)
+ money (3.7.1)
+ i18n (~> 0.4)
+ multi_json (1.0.4)
+ mysql2 (0.3.11)
+ nested_set (1.6.8)
+ activerecord (>= 3.0.0)
+ railties (>= 3.0.0)
+ nokogiri (1.5.0)
+ paper_trail (2.6.0)
+ rails (~> 3)
+ paperclip (2.5.0)
+ activerecord (>= 2.3.0)
+ activesupport (>= 2.3.2)
+ cocaine (>= 0.0.2)
+ mime-types
+ polyamorous (0.5.0)
+ activerecord (~> 3.0)
+ polyglot (0.3.3)
+ rack (1.3.6)
+ rack-cache (1.1)
+ rack (>= 0.4)
+ rack-mount (0.8.3)
+ rack (>= 1.0.0)
+ rack-ssl (1.3.2)
+ rack
+ rack-test (0.6.1)
+ rack (>= 1.0)
+ rails (3.1.3)
+ actionmailer (= 3.1.3)
+ actionpack (= 3.1.3)
+ activerecord (= 3.1.3)
+ activeresource (= 3.1.3)
+ activesupport (= 3.1.3)
+ bundler (~> 1.0)
+ railties (= 3.1.3)
+ railties (3.1.3)
+ actionpack (= 3.1.3)
+ activesupport (= 3.1.3)
+ rack-ssl (~> 1.3.2)
+ rake (>= 0.8.7)
+ rdoc (~> 3.4)
+ thor (~> 0.14.6)
+ rake (0.9.2.2)
+ rdoc (3.12)
+ json (~> 1.4)
+ rspec (2.8.0)
+ rspec-core (~> 2.8.0)
+ rspec-expectations (~> 2.8.0)
+ rspec-mocks (~> 2.8.0)
+ rspec-core (2.8.0)
+ rspec-expectations (2.8.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.8.0)
+ rspec-rails (2.8.1)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec (~> 2.8.0)
+ ruby-debug-base19 (0.11.25)
+ columnize (>= 0.3.1)
+ linecache19 (>= 0.5.11)
+ ruby_core_source (>= 0.1.4)
+ ruby-debug19 (0.11.6)
+ columnize (>= 0.3.1)
+ linecache19 (>= 0.5.11)
+ ruby-debug-base19 (>= 0.11.19)
+ ruby_core_source (0.1.5)
+ archive-tar-minitar (>= 0.5.2)
+ rubyzip (0.9.6.1)
+ sass (3.1.15)
+ selenium-webdriver (2.19.0)
+ childprocess (>= 0.2.5)
+ ffi (~> 1.0.9)
+ multi_json (~> 1.0.4)
+ rubyzip
+ spree_core (1.0.0)
+ activemerchant (= 1.20.1)
+ acts_as_list (= 0.1.4)
+ deface (>= 0.7.2)
+ ffaker (~> 1.12.0)
+ highline (= 1.6.8)
+ jquery-rails (>= 1.0.18, <= 1.0.19)
+ kaminari (>= 0.13.0)
+ meta_search (= 1.1.1)
+ nested_set (= 1.6.8)
+ paperclip (= 2.5.0)
+ rails (>= 3.1.1, <= 3.1.3)
+ state_machine (= 1.1.1)
+ stringex (~> 1.3.0)
+ sprockets (2.0.3)
+ hike (~> 1.2)
+ rack (~> 1.0)
+ tilt (~> 1.1, != 1.3.0)
+ sqlite3 (1.3.5)
+ state_machine (1.1.1)
+ stringex (1.3.0)
+ thor (0.14.6)
+ tilt (1.3.3)
+ treetop (1.4.10)
+ polyglot
+ polyglot (>= 0.3.1)
+ tzinfo (0.3.31)
+ xpath (0.1.4)
+ nokogiri (~> 1.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ capybara (= 1.0.1)
+ factory_girl
+ ffaker
+ mysql2
+ rspec-rails (~> 2.7)
+ ruby-debug19
+ spree_multi_lingual!
+ sqlite3
26 LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2012 [name of plugin creator]
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name Spree nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 README.md
@@ -0,0 +1,33 @@
+SpreeMultiLingual
+=================
+This is a proof of concept for what could become a multi-lingual Spree store plugin.
+
+Warning: code quality is from so-so to poor. Just wanted to put out something before Spreeconf so we could discuss and maybe hack around it.
+
+Notes
+-----
+
+Set SpreeMultiLingual.languages to an array containing the languages you support. You might want to set that in config/initializers/spree_multi_lingual.rb or something like that.
+
+ SpreeMultiLingual.languages = ["fr", "en", "es"]
+
+There is no fallback of default language for now!
+
+It uses Globalize3. Some code inspired from [https://github.com/tomash/spree_globalize](https://github.com/tomash/spree_globalize) (even took some pieces of code! Especially the "globalize_accessors" method. Why reinvent the wheel when you don't have to?)
+
+
+Example
+=======
+
+Example goes here.
+
+Testing
+-------
+
+Be sure to bundle your dependencies and then create a dummy test app for the specs to run against.
+
+ $ bundle
+ $ bundle exec rake test app
+ $ bundle exec rspec spec
+
+Copyright (c) 2012 Jean-Philippe Boily, released under the New BSD License
29 Rakefile
@@ -0,0 +1,29 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/packagetask'
+require 'rubygems/package_task'
+require 'rspec/core/rake_task'
+require 'spree/core/testing_support/common_rake'
+
+RSpec::Core::RakeTask.new
+
+task :default => [:spec]
+
+spec = eval(File.read('spree_multi_lingual.gemspec'))
+
+Gem::PackageTask.new(spec) do |p|
+ p.gem_spec = spec
+end
+
+desc "Release to gemcutter"
+task :release => :package do
+ require 'rake/gemcutter'
+ Rake::Gemcutter::Tasks.new(spec).define
+ Rake::Task['gem:push'].invoke
+end
+
+desc "Generates a dummy app for testing"
+task :test_app do
+ ENV['LIB_NAME'] = 'spree_multi_lingual'
+ Rake::Task['common:test_app'].invoke
+end
9 Versionfile
@@ -0,0 +1,9 @@
+# This file is used to designate compatibilty with different versions of Spree
+# Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details
+
+# Examples
+#
+# "0.70.x" => { :branch => "master"}
+# "0.60.x" => { :branch => "0-60-stable" }
+# "0.40.x" => { :tag => "v1.0.0", :version => "1.0.0" }
+
45 app/assets/javascripts/admin/spree_multi_lingual.js
@@ -0,0 +1,45 @@
+//= require admin/spree_core
+//= require admin/spree_multi_lingual_class
+
+
+// $(document).ready(function(){
+//
+// $("#spree_multi_lingual_dropdown").change(function(e){
+// SpreeMultiLingual.change_language();
+// });
+// });
+
+
+// var SpreeMultiLingual = {};
+// (SpreeMultiLingual = function () {
+// SpreeMultiLingual.translated_fields = [];
+//
+// SpreeMultiLingual.change_language = function () {
+// set_translated_fields();
+// for_each_field(function(field){
+// alert(field);
+// });
+// }
+//
+// SpreeMultiLingual.duplicate_fields = function(){
+//
+// }
+//
+// SpreeMultiLingual.field_exists_for_language = function(){
+//
+// }
+//
+// set_translated_fields = function(){
+// if(SpreeMultiLingual.translated_fields.length == 0){
+// $("input[name='translated_fields']").each(function(i, field){
+// SpreeMultiLingual.translated_fields[i] = $(field).val();
+// });
+// }
+// }
+//
+// for_each_field = function(callback){
+// for(var i = 0; i > SpreeMultiLingual.translated_fields.length; i++){
+// eval(callback + "(" + SpreeMultiLingual.translated_fields[i] + ")");
+// }
+// }
+// })();
46 app/assets/javascripts/admin/spree_multi_lingual_class.js.coffee
@@ -0,0 +1,46 @@
+$(document).ready ->
+ $("#spree_multi_lingual_dropdown").change (e) ->
+ ml = new SpreeMultiLingual
+ ml.change_language(@.value)
+
+class SpreeMultiLingual
+ constructor: ->
+ @translated_fields = window.spree_multi_lingual.translated_fields
+ @default_locale = window.spree_multi_lingual.backend_locale
+ @current_locale = @default_locale
+
+ change_language: (locale) =>
+ @current_locale = locale
+ @make_sure_field_exists_for_language()
+ @show_fields()
+
+ duplicate_field: (field) =>
+ field_name = @localized_field_name(field)
+ new_field_name_value = $("#" + field).attr("name").substring(0,$("#" + field).attr("name").length - 1) + "_" + @current_locale + "]"
+ new_field = $("#" + field).clone().attr("id", field_name).attr("name", new_field_name_value).removeClass("sml-localized-field-"+@default_locale)
+ value = eval("window.spree_multi_lingual.translated_fields_values['#{field_name}']")
+ new_field.val(value) if value
+ $("#" + field).after(new_field)
+ @add_localized_class(field_name)
+ @add_localized_class(field, @default_locale)
+
+ make_sure_field_exists_for_language: =>
+ for field in @translated_fields
+ field_name = @localized_field_name(field)
+ if !$("#" + field_name).length
+ @duplicate_field(field)
+
+ show_fields: =>
+ $(".sml-localized-field").hide()
+ $(".sml-localized-field-#{@current_locale}").show()
+
+ localized_field_name: (field) =>
+ return (field + "_" + @current_locale) if @current_locale isnt @default_locale
+ field
+
+ add_localized_class: (id, locale = @current_locale) =>
+ @add_class(id, "sml-localized-field")
+ @add_class(id, "sml-localized-field-" + locale)
+
+ add_class: (id, klass) ->
+ $("#" + id).addClass(klass) unless $("#" + id).hasClass(klass)
1  app/assets/javascripts/store/spree_multi_lingual.js
@@ -0,0 +1 @@
+//= require store/spree_core
3  app/assets/stylesheets/admin/spree_multi_lingual.css
@@ -0,0 +1,3 @@
+/*
+ *= require admin/spree_core
+*/
3  app/assets/stylesheets/store/spree_multi_lingual.css
@@ -0,0 +1,3 @@
+/*
+ *= require store/spree_core
+*/
4 app/models/product_decorator.rb
@@ -0,0 +1,4 @@
+Spree::Product.class_eval do
+ translates :name, :description
+ globalize_accessors SpreeMultiLingual.languages
+end
5 app/overrides/product_add_language_dropdown.rb
@@ -0,0 +1,5 @@
+Deface::Override.new(
+ :virtual_path => "spree/admin/products/_form",
+ :insert_top => "[data-hook='admin_product_form_left']",
+ :partial => "spree/admin/spree_multi_lingual/products/language_dropdown",
+ :name => "product_add_language_dropdown")
5 config/locales/en.yml
@@ -0,0 +1,5 @@
+# Sample localization file for English. Add more files in this directory for other locales.
+# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
+
+en:
+ hello: "Hello world"
3  config/routes.rb
@@ -0,0 +1,3 @@
+Spree::Core::Engine.routes.draw do
+ # Add your extension routes here
+end
8 db/migrate/20120213172418_add_translation_to_product_name_and_description.rb
@@ -0,0 +1,8 @@
+class AddTranslationToProductNameAndDescription < ActiveRecord::Migration
+ def up
+ Spree::Product.create_translation_table! :name => :string, :description => :text
+ end
+ def down
+ Spree::Product.drop_translation_table!
+ end
+end
34 lib/active_record/globalize_accessors.rb
@@ -0,0 +1,34 @@
+module ActiveRecord
+ module GlobalizeAccessors
+ def self.included(base)
+ base.extend ActMethods
+ end
+
+ module ActMethods
+ def globalize_accessors(languages)
+ attribs = translated_attribute_names
+ attribs.each do |attr_name|
+ languages.each do |with_locale|
+ define_method :"#{attr_name}_#{with_locale}" do
+ globalize.fetch with_locale, attr_name
+ end
+
+ define_method :"#{attr_name}_#{with_locale}=" do |val|
+ globalize.stash.write with_locale, attr_name, val
+ end
+ end
+ end
+
+ @easy_accessors ||= []
+ languages.each do |with_locale|
+ @easy_accessors << with_locale
+ end
+
+ end
+
+ def easy_accessors
+ @easy_accessors && @easy_accessors.uniq
+ end
+ end
+ end
+end
29 lib/generators/spree_multi_lingual/install/install_generator.rb
@@ -0,0 +1,29 @@
+module SpreeMultiLingual
+ module Generators
+ class InstallGenerator < Rails::Generators::Base
+
+ def add_javascripts
+ append_file "app/assets/javascripts/store/all.js", "//= require store/spree_multi_lingual\n"
+ append_file "app/assets/javascripts/admin/all.js", "//= require admin/spree_multi_lingual\n"
+ end
+
+ def add_stylesheets
+ inject_into_file "app/assets/stylesheets/store/all.css", " *= require store/spree_multi_lingual\n", :before => /\*\//, :verbose => true
+ inject_into_file "app/assets/stylesheets/admin/all.css", " *= require admin/spree_multi_lingual\n", :before => /\*\//, :verbose => true
+ end
+
+ def add_migrations
+ run 'bundle exec rake railties:install:migrations FROM=spree_multi_lingual'
+ end
+
+ def run_migrations
+ res = ask "Would you like to run the migrations now? [Y/n]"
+ if res == "" || res.downcase == "y"
+ run 'bundle exec rake db:migrate'
+ else
+ puts "Skiping rake db:migrate, don't forget to run it!"
+ end
+ end
+ end
+ end
+end
3  lib/spree_multi_lingual.rb
@@ -0,0 +1,3 @@
+require 'spree_core'
+require 'spree_multi_lingual/engine'
+require "globalize3"
29 lib/spree_multi_lingual/engine.rb
@@ -0,0 +1,29 @@
+module SpreeMultiLingual
+ mattr_accessor :languages
+
+ class Engine < Rails::Engine
+ engine_name 'spree_multi_lingual'
+
+ config.autoload_paths += %W(#{config.root}/lib)
+
+ # use rspec for tests
+ config.generators do |g|
+ g.test_framework :rspec
+ end
+
+ def self.activate
+ #easy-globalize-accessors functionality
+ ActiveRecord::Base.send :include, ActiveRecord::GlobalizeAccessors
+
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_decorator*.rb")) do |c|
+ Rails.configuration.cache_classes ? require(c) : load(c)
+ end
+
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/overrides/*.rb")) do |c|
+ Rails.configuration.cache_classes ? require(c) : load(c)
+ end
+ end
+
+ config.to_prepare &method(:activate).to_proc
+ end
+end
5 script/rails
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
+
+ENGINE_PATH = File.expand_path('../..', __FILE__)
+load File.expand_path('../../spec/dummy/script/rails', __FILE__)
32 spec/spec_helper.rb
@@ -0,0 +1,32 @@
+# Configure Rails Environment
+ENV["RAILS_ENV"] = "test"
+
+require File.expand_path("../dummy/config/environment.rb", __FILE__)
+
+require 'rspec/rails'
+
+# Requires supporting ruby files with custom matchers and macros, etc,
+# in spec/support/ and its subdirectories.
+Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each {|f| require f }
+
+# Requires factories defined in spree_core
+require 'spree/core/testing_support/factories'
+
+RSpec.configure do |config|
+ # == Mock Framework
+ #
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
+ #
+ # config.mock_with :mocha
+ # config.mock_with :flexmock
+ # config.mock_with :rr
+ config.mock_with :rspec
+
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
+ # examples within a transaction, remove the following line or assign false
+ # instead of true.
+ config.use_transactional_fixtures = true
+end
34 spree_multi_lingual.gemspec
@@ -0,0 +1,34 @@
+# encoding: UTF-8
+Gem::Specification.new do |s|
+ s.platform = Gem::Platform::RUBY
+ s.name = 'spree_multi_lingual'
+ s.version = '0.1.0.alpha1'
+ s.summary = 'Proof of concept for a multi-lingual Spree store plugin'
+ s.description = 'This is a proof of concept for what could become a multi-lingual Spree store plugin. Warning: code quality is from so-so to poor. Just wanted to put out something before Spreeconf so we could discuss and maybe hack around it.'
+ s.required_ruby_version = '>= 1.8.7'
+
+ s.author = 'Jean-Philippe Boily | @jipiboily'
+ s.email = 'j@jipi.ca'
+ s.homepage = 'http://github.com/jipiboily/spree_multi_lingual'
+
+ #s.files = `git ls-files`.split("\n")
+ #s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.require_path = 'lib'
+ s.requirements << 'none'
+
+ s.add_dependency 'spree_core', '~> 1.0.0'
+ s.add_dependency 'i18n'
+ s.add_dependency 'globalize3', '~> 0.2.0.beta8'
+
+ s.add_dependency 'coffee-rails'
+
+ s.add_development_dependency 'capybara', '1.0.1'
+ s.add_development_dependency 'factory_girl'
+ s.add_development_dependency 'ffaker'
+ s.add_development_dependency 'rspec-rails', '~> 2.7'
+ s.add_development_dependency 'sqlite3'
+ s.add_development_dependency 'mysql2'
+
+ # Seems Spree doesn't require it correctly or there is a problem with extensions maybe? Still, it is needed to work with the dummy app!
+ s.add_dependency 'sass'
+end
Please sign in to comment.
Something went wrong with that request. Please try again.