Setup Commands
gem install compass nvm install 0.10.33 nvm use 0.10.33 npm install npm install -g grunt-cli npm install -g bower bower install
Test Commands
grunt test
gem install compass nvm install 0.10.33 nvm use 0.10.33 npm install npm install -g grunt-cli npm install -g bower bower install
grunt test
Notes around creating a Rails 4.1.8 application on JRuby 1.7.16.1.
Using RVM to manage my rubies.
rvm use jruby-1.7.16.1 gem install rails rails new .
Add the following to the Gemfile.
gem 'activerecord-jdbcpostgresql-adapter'
ruby '1.9.3', :engine => 'jruby', :engine_version => '1.7.16.1'
My Gemfile as it currently stands:
source 'https://rubygems.org' ruby '1.9.3', :engine => 'jruby', :engine_version => '1.7.16.1' gem 'rails', '4.1.8' gem 'activerecord-jdbcpostgresql-adapter' gem 'sass-rails', '~> 4.0.3' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' gem 'therubyrhino' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 2.0' gem 'sdoc', '~> 0.4.0', group: :doc gem 'puma'
Set up your databases environments, similar to what I have here:
default: &default adapter: jdbcpostgresql encoding: unicode development: <<: *default host: localhost database: foobar_development username: postgres password: postgres test: <<: *default host: localhost database: foobar_test username: postgres password: postgres production: <<: *default host: localhost database: foobar_production username: postgres password: postgres
config.vm.network "forwarded_port", guest: 5432, host: 15432
. I'm using Vagrant 1.6.3 here. Start/restart your Vagrant image.
host all all 127.0.0.1/32 trustto
host all all 0.0.0.0/0 trust
sudo service postgresql restart
plugins: [ 'karma-jasmine', 'karma-coverage', 'karma-junit-reporter', 'karma-phantomjs-launcher', 'karma-chrome-launcher', 'karma-safari-launcher', 'karma-firefox-launcher', 'karma-ie-launcher' ],I also needed to install these node packages and save the configuration to the package.json file:
npm install karma-jasmine --save-dev npm install karma-coverage --save-dev npm install karma-junit-reporter --save-dev npm install karma-phantomjs-launcher --save-dev npm install karma-safari-launcher --save-dev npm install karma-firefox-launcher --save-dev
brew install redis
redis-server /usr/local/etc/redis.conf
redis-cli monitor
Now that we have Redis up and running, get websocket-rails integrated into your application. I won't belabor how to do that--the documentation does a good job of detailing how. I use a channel to communicate from the client-side and the server-side. Another thing to note is that for anything I do on the client that I want an event for coming from the server, I use a correlation ID from the client-side that I can keep track of on the client-side, so when an event from the server-side is received, I can determine whether I'm interested in it because it contains the original correlation ID. Read more here about the correlation ID design pattern.
heroku certs:remove
, then remove SSL support through the Dashboard.heroku labs:enable websockets
if ENV["RAILS_ENV"] == 'production' config.redis_options = { username: 'rediscloud', password: 'UHDDBHD&*#$DFkkdfha', host: 'pub-redis-88885.us-east-1-3.3.ec2.redisdomecity.com', port: '15204' } else config.redis_options = { host: 'localhost', port: '6379' } endThis will invariably change so I can differentiate between staging and production, but you get the point.
cc -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -pipe -arch x86_64 -DHAVE_LIBJPEG -DHAVE_LIBZ -I/System/Library/Frameworks/Tcl.framework/Headers -I/System/Library/Frameworks/Tk.framework/Headers -I/usr/local/include/freetype2 -IlibImaging -I/System/Library/Frameworks/Python.framework/Versions/2.7/include -I/usr/local/include -I/usr/include -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c _imaging.c -o build/temp.macosx-10.9-intel-2.7/_imaging.o clang: error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future] clang: note: this will be a hard error (cannot be downgraded to a warning) in the future error: command 'cc' failed with exit status 1
Just a quick note: the Copy as HTML plugin does not show up in the RubyMine 6 plugins listing. But if you download it from here, and install it from disk through the Plugins preferences page, it will work flawlessly in RubyMine. Not sure why it does get listed, but it's a great plugin nonetheless.
I've been doing a bunch of RubyMotion development lately and I'm continually amazed at the power of this framework. One of the many great tools available to RubyMotion developers is Teacup, a UI view layout and styling domain-specific library (DSL). I think DSLs are one of the big advantages that RubyMotion has over traditional native iOS development using Objective-C and Xcode. More information on Teacup here. There's tons of documentation around using Teacup with UIViewControllers, but scant documentation on using Teacup with custom UIView components. There are times that you cannot style a UIView or subclass when the view is initially rendered. Examples include table cells and table headers. Well, don't fear, because you can always mix-in the Teacup layout behavior into any old Ruby class and get that functionality. Below is a table view header helper class that creates new UIView objects with a UILabel subview. Notice how I mix in the Teacup::Layout behavior into the helper and then I have access to all the Teacup stylesheet and layout functionality.
1 class TableViewHeaderHelper 2 include Teacup::Layout 3 4 stylesheet :table_view_header 5 6 def create(frame, title) 7 view = UIView.alloc.initWithFrame(frame) 8 view.stylename = :root 9 layout(view) do 10 label = subview(UILabel, :label) 11 label.text = title 12 end 13 view 14 end 15 16 end
In this above example, the factory method takes a frame and a title for the header. I create the root UIView and then pass that to the Teacup layout to do the rest of the composite magic. Since the title is dynamic, I get a reference to the created UILabel and set the text of the label to the title string passed into the factory method.
Next up is the Teacup stylesheet. This sits in app/styles/styles.rb in my RubyMotion application. I defined a couple of global UIColor objects and then define the table_view_header style for use in the TableViewHeaderHelper class previously shown. The rest of this is standard Teacup functionality, so I won't repeat what they have already documented.
1 sectionBackgroundColor = UIColor.colorWithRed(221/255.0, 2 green: 238/255.0, 3 blue: 249/255.0, 4 alpha: 1.0) 5 headerTextColor = UIColor.colorWithRed(50/255.0, 6 green: 50/255.0, 7 blue: 50/255.0, 8 alpha: 1.0) 9 10 Teacup::Stylesheet.new :table_view_header do 11 12 style :root, 13 backgroundColor: sectionBackgroundColor 14 15 style :label, 16 top: 1, 17 left: 15, 18 width: 500, 19 height: 40, 20 font: :bold.uifont(20), 21 textColor: headerTextColor 22 end
Finally are the UITableViewDelegate protocol methods that I implemented to get a custom header for my UITableView. Note that the frame height used for constructing the UIView in the TableViewHeaderHelper is ignored, and the UITableViewDelegate heightForHeaderInSection:section method is used to determine the header height instead. Kind of strange, but it works.
1 def tableView(tableView, viewForHeaderInSection: section) 2 frame = CGRectMake(0, 0, tableView.frame.size.width, 1) 3 title = "#{@league.name}: My Stations by date" 4 TableViewHeaderHelper.new.create(frame, 5 title) 6 end 7 8 def tableView(tableView, heightForHeaderInSection:section) 9 50 10 end
This is more a note for myself. When using forward, a SSH tunnel Ruby gem from the folks at forwardhq.com, Google App Engine\Python devserver will barf trying to resolve the Host header when dispatching tasks on the task queue. In my case, my tunnel hostname was coming through in the Host header, causing the KeyError in _port_registry.get(port)
invocation.
dispatcher.py
def _resolve_target(self, hostname, path): if self._port == 80: default_address = self.host else: default_address = '%s:%s' % (self.host, self._port) if not hostname or hostname == default_address: return self._module_for_request(path), None default_address_offset = hostname.find(default_address) if default_address_offset > 0: prefix = hostname[:default_address_offset - 1] # The prefix should be 'module', but might be 'instance.version.module', # 'version.module', or 'instance.module'. These alternatives work in # production, but devappserver2 doesn't support running multiple versions # of the same module. All we can really do is route to the default # version of the specified module. if '.' in prefix: logging.warning('Ignoring instance/version in %s; multiple versions ' 'are not supported in devappserver.', prefix) module_name = prefix.split('.')[-1] return self._get_module_with_soft_routing(module_name, None), None else: if ':' in hostname: port = int(hostname.split(':', 1)[1]) else: port = 80 try: _module, inst = self._port_registry.get(port) except KeyError: raise request_info.ModuleDoesNotExistError(hostname) _module, inst = None, None if not _module: _module = self._module_for_request(path) return _module, inst
The line in red is the line that is barfing. Comment out the raise error line and set _module and inst to None, allowing execution to continue and the next line will test if _module hasn't been set and will go ahead and resolve it. Found the temporary fix from https://github.com/dylanvee/homebrew-gae_sdk. Hopefully this is something the GAE people can fix in upcoming versions of GAE\Python SDK.