components snippets

How to use Rails Engines

Tagged rails, engines, microservices, components  Languages ruby

Create a new engine named x:

$ rails plugin new x --mountable

Load the engine by modifying Gemfile:

gem 'x', path: 'engines/x'

Mount the engine as root in config/routes.rb:

mount X::Engine => ”/”, as: ’root’

Optionally, allow the engine to override views and assets by adding this to config/application.rb:

ApplicationController.prepend_view_path Rails.root.join('engines', 'x', 'app', 'views')

%w(stylesheets javascripts images).each do |dir|
  Rails.configuration.assets.paths.unshift Rails.root.join('engines', 'x', 'app', 'assets', dir)
end

Resources

https://github.com/shageman/the\_next\_big\_thing http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/ http://pivotallabs.com/unbuilt-rails-dependencies-how-to-design-for-loosely-coupled-highly-cohesive-components-within-a-rails-application/ http://pivotallabs.com/experience-report-engine-usage-that-didn-t-work/ http://assets.pivotallabs.com/1439/original/2012\_06\_12\_wrangling\_large\_rails\_codebases.pdf http://microservices.io/patterns/monolithic.html

Automatic Instantiation of Web Components Written in JavaScript/Coffeescript

Tagged components  Languages coffeescript

Your app.js.coffee:

$ ->
  for component in $('.web-component')
    component = $(component)
    class_name = component.data('class')
    id = "#" + component.attr('id')
    component_class = eval.call(window, class_name)
    if component_class
      console.debug("Creating #{class_name}")
      try
        new component_class(id)
      catch error
        console.log "Failed to create #{class_name}"
    else
      throw "UI component '#{class_name}' does not exist."

Declare a web component in your view:

<div id="alerts" class="web-component" data-class="App.Alerts"/>

Write your web component, e.g. app/assets/javascripts/components/alert.js.coffee:

root = exports ? this
# declared elsewhere
# root.App = {}

class Alerts
....

root.App.Alerts = Alerts

Getting Started With React.js and Rails

Tagged coffeescript, rails, react.js, components  Languages ruby

Why use React.js?

  • React ~35kb vs. Amber.js ~100kb
  • Easy to learn compared to Ember.js and Angular.js
  • Supports server-side rendering
  • Great performance
  • Angular.js documentation is horrible
  • Angular.js is the new EJB

Why shouldn't you use React.js?

  • React.js is difficult to integrate with JS libraries that move or create DOM elements, e.g. jQuery UI
  • React.js is still evolving. Expect API changes to break your app.

Installation

Gemfile:

gem 'active_model_serializers' # You probably want this gem too...
gem 'react-rails', '~> 1.0.0.pre', github: 'reactjs/react-rails'

From the console run:

bundle
rails g react:install

Make sure you have this in app/assets/javascript/application.js:

# ...
#= require react
# For the <div data-react-class...> syntax
#= require react_ujs
#= require_tree components

Add this to config/environments/production.rb

Rails.config.react.variant = :production

And this to config/environments/development.rb

Rails.config.react.variant = :development

Hello World

Create app/assets/javascripts/components/hello.jsx.coffee (note the file extension):

###* @jsx React.DOM ###

window.Hello = React.createClass
  render: ->
    <div>{this.props.name}</div>

app/views/layouts/application.html.erb

<html>
…
  <div data-react-class="Hello" data-react-props=<%= { name: 'John' }.to_json %>/>
or:
  <%= react_component 'Hello', name: 'John' %>
....
</html>

Troubleshooting

  • Unexpected token '<' Error

Did you forget to add this to the top of your React component file (.js.jsx)?

/** @jsx React.DOM */

or this to your CoffeeScript component (.jsx.coffee):

###* @jsx React.DOM ###
  • Target container is not a DOM element.

Does the DOM element exist?

Did you forget to call React.renderComponent in jQuery’s $(document).ready?

  • Adjacent XJS elements must be wrapped in an enclosing tag

Multiple nodes need a parent element:

<ul> // Doesn't work without <ul> wrapper
  <li></li>
  <li></li>
</ul>
  • Still doesn’t work?

react-rails is not stable; expect it to break.

Gotchas

Solutions: React.js Google Group React.js and jQuery sortable React.js and select2 React.js and Bootstrap Modal React.js and Kendo UI

  • You need to change the HTML "class" attribute to "className" in JSX