Rails project with React Rails directories? - ruby-on-rails

Image showing my rails structure for react
I have a lot of react components and wish to simply keep them better organized. So I'll cut to the chase and just ask. Is it possible to put my react components in directories and if so- how do I select them in a view and other react components?
I've already tried a few variatians like the one below without success and fear that it's simply not possible? Can't find any documentation about this either.
<%= react_component('OutfitCreate.Images') %>
Edit: To clarify, I want to make it clear that I'm using a typical rails project structure, and for react I am making use of the react-rails gem to handle my components as well as generating them.
Edit2: To clarify further, what I'm seeking is a way to target a react component by directory as such:
<%= react_component('<directory>/<classname>') %>
where each directory will be sub directories of "components".

I know this is an old question but maybe it helps anyone. You can do it like this:
<%= react_component "ComponentFolder/ComponentClassName" %>
It works just fine with rails-react and webpacker.

I recently used the react-rails gem and had a good experience. It takes care of accessing your components in Rails templates and does a few other nice things.
To answer your question specifically, you can put your components inside as many directories as you like as long as you follow the gem docs. The gem provides a view helper that allows you to render a specific component, and to pass data to it as props (the helper takes a hash which becomes the component's props).
Edit -- I'm not sure if you're already using the gem, the helper method you are using looks like it, but you don't specifically mention it. Perhaps there is a problem with the gem installation and/or setup. You need to edit application.js and also to run the generator task: rails g react:install
Edit -- To make sure you can access components in the components subdirectory, you should do the following things:
*run the generator: rails g react:install
*make sure the generated components.js file contains: //= require_tree ./components
*make sure your application.js file contains:
//= require react
//= require react_ujs
//= require components

React components will be considered global, because all .js will be minified in one single big .js file. So, you will have to take some considerations.
First, in your sprockets file (Normally application.js) you need to tell Rails to serve the React Components you want. The easy way would be to require all folders and files in components folder, because all your components will be there, but organized in subfolders. This is made adding the next line:
// File: app/assets/javascripts/application.js
//= require_tree ./components
Second, if you want to use your React component named for example Images, which could be defined in ../components/folder/images.js, you just could use in your Rails View the helper react_component('Images') like usual.
React will find the Images component if it match with the Images component you defined inside some served .js (But a sane human will expect you defined the Image Component inside some images.js) because this name Images is global (Remember? One big .js file will be served).
With this approach, the client will download only one big .js file with all your React Components. Bad for download speed, but could be cached.
So, here, you would have to take care to name all components with a different name each one.
Now, if you have for example a component named Foo inside ../components/folder/doesnt_matter.js and another component with the same name Foo, but inside ../components/another_folder/this_neither.js, you will have to tell Rails which file do you want to serve for the specific View you want to render to evade collision name problems.
This means, you could make the client to download only the needed js code (and the needed React Components) for the rendered page. It will be downloading .js files for each page, losing the cache possibility.
One intermediate way to do this, would be to serve a middle sized .js file for all the views in the same controller.
To do this, you could organize your js (or jsx, or ...) in a way you could have a place for common Components (which are used in two or more controllers), and a specific folder for each controller with specific React Components in there.
First, you will have to replace the previously added //require_tree ./components in application.js with //require ./components/common/ for serving only the common React components to All Views.
Second, in your layout, you could serve two js files; an application.js and a #{controller_name}.js (This means, one specific .js file per controller).
Third, for each controller, you will have a .js file with the same name. So, supose you have a controller called home_controller, then, you will need to have a home.js (controller_name helper in layout view will make rails to look for this file) and in it, using sprockets again, you will serve specific React Components with //require ./components/home/
In this way, you will have to take care of your organization, and the React Components Names need to differ with the ones inside .../components/common/.
If you want to be more specific yet, you could use the same technique in layout in combination with controller_name and action_name helpers. Or you could use content_for asking for the specific .js files that have the React Components the View needs.
However, you need to be carefull because i don't know how crazy the Assets Pipeline could turn against you. Specially using content_for.

Related

Add subdirectories to Rails assets

I am trying to integrate a Bootstrap framework into a Rails project. The framework comes with lots of html templates which I would like to use. Each template has several links to assets (css, images, js) which are all named something like:
href="assets/css/stylesheet.css"
By including the framework's files in the Rails vendor/assets folder I can access all these resources if I rename them all to
href="assets/stylesheet.css"
or using a Rails helper, but I don't want to have to do that for every single asset because I'd rather leave as much of the framework intact as possible for updates and such, and besides that would be super annoying to deal with.
Is there a way to have Rails access these files the way they are currently written?
(I know for example this is possible with Laravel Elixir).
The standard procedure here is to add references to these in your application.css or equivalent file. There's usually a comment in that master file that looks like this:
/*
*= require_tree .
*= require_self
*/
You can add other files to that manually, or just put your assets in there in a way that they get hoovered up properly by the asset pipeline.
Doing this means they all get packed down into the same distributable CSS file when you roll this out to production.
If you do want to compile this separately for whatever reason you need to alter config/initializers/assets.rb and add things like:
Rails.application.config.assets.precompile += %w[
assets/stylesheet.css
]
That will force-compile another unrelated asset.

Angular ui bootstrap custom templates in Rails

How can I use the custom templates of angular ui bootstrap in rails?
I mean, if I use pagination for example it will look for a templates/pagination/pagination.html template.
The problem is that rails won't serve templates in that path, it actually needs to be assets/templates/pagination/pagination.html using the <%= asset_path(....) %> helper.
Hacking the angular ui bootstrap javascript file is a way, but I don't feel like hacking it every time I get a new version.
What I would suggest is to bundle custom templates with the library itself or inside a separate file. The technique to use is to fill in $templateCache with the content of your custom templates. Have a look at one of the files distributed with tamplates to see what I mean:
https://github.com/angular-ui/bootstrap/blob/gh-pages/ui-bootstrap-tpls-0.3.0.js#L2042
You can bundle templates into the $templateCache as part of the build process or prepare this file manually (in this case you need to write templates as JS strings).
Downloading individual templates via XHR for each and every directive would be wasteful as it would result in many XHR requests and would slow down your application. Also, if you preload templates into the $templateCache you can specify required path, one that doesn't need to be a valid path on your WWW server.
I use bower to manage my js libs.
Hence I have these files in my vendor/assets/javascripts/ folder:
angular-ui/bootstrap-bower
With these files, you can simply require them in your javascript manifest file (usually application.js)
//= require angular-bootstrap/ui-bootstrap
//= require angular-bootstrap/ui-bootstrap-tpls
and then you don't need to specify any templates if you want to use the default built-in templates.
I find this solution in the following url
Ref:angular-ui-bootstrap-directive-template-missing

How to add wrapbootstrap (made with twitter bootstrap) themes to rails application

The website https://wrapbootstrap.com/ has themes which were made using Twitter Bootstrap. Each of these themes include different versions of Twitter Bootstrap along with other various libraries and versions (jquery, fontawesome, etc...)
How do I add these themes to my existing Rails app? What are the steps?
I'm especially curious about the conflicts that may arrise if I'm already using a different version of jquery, twitter bootstrap, fontawesome, and others (as declared in the Gemfile).
Thank you
You can add the css from the theme you purchased from wrapbootstrap to your assets > application.css.scss file. And use the html tags that came with the theme in your rails app views so that the css styling is applied.
Also, I would recommend using gem 'sass-rails' to import the standard bootstrap styling.
Here's a tutorial to get you started with adding bootstrap to a rails app. Adding the theme css and html tags is up to you.
http://railscasts.com/episodes/328-twitter-bootstrap-basics?view=asciicast
I did this for few of the projects, I agree with majorly what Mike has answered above. Here are some of the gotchas I saw.
We started as a standard project on Rails all our views dynamic(Ember)/static were based on Bootstrap CSS. When major internal pages were up and functionality demonstrated we focused on landing pages. By this time we had the gems for bootstrap, fontawesome added to our Gemfile.
So one of the thing is to remove these gems "bootstrap", "fontawesome" from Gemfile. Include these as part of your wrapbootstrap dump.
Also as you progress with integration you may realize that a lot of common code is being repeated, its in your best interest to split the page components: headers, footers other things as partial Rails views. It severely saves the editing effort.
Another thing I found extremely useful to keep every thing up while you are still in integration stage, is to split your CSS/JS includes for pages imported from wrap bootstrap and pages you already have. So if you intend to migrate all existing pages into new theme scraping your CSS, then it can be merged in stages, otherwise you can let them co-exist.
You have to add new entries in routes.rb, controller calls to support the pages if you don't have them already. Likes of about, contactus, team etc. etc.
And if you use something like Ember/Backbone then you have to manage the co-existence of single pager app in some pages which may or may not be linked to the Wrapbootstrap pages.
This was all the things I had to take care off when I integrated the wrapbootstrap theme on top of Rails-EmberJS app.
Interesting timing as I just had to do this myself. I'm still fairly new to Rails so this might not be the best solution, but here's how I got it working ...
Note: every theme is different so this may not be a one size fits all approach.
1) My theme was built with Middleman and it was expecting to run stand alone or on a Sinatra instance.
2) In order to get the theme up on Rails, I had to add the compass gem, the sass gem, the sass-rails gem, and the compass-rails gem to work properly. I'm assuming you can install these (if required for your theme).
3) Assuming you have a Rails app ready to roll, go into your assets directory and backup your .js, .css, and all fonts and images. Place your theme asset files in the appropriate place.
4) Now do the same with your view layer. You may have a partials and/or pages folder which you can place in the views directory. You'll want to put application.erb.html and any navigation files in the layouts folder under the views directory. Again, make sure you back up your original files first.
5) If your theme was designed for Sinatra, you may have a Config.rb file. I moved the logic from this file into my config/environment.rb file. I was the least confident with this step. Other Rails devs can chime in if there is a better location.
6) Start your server up. You may encounter some exceptions but this is to be expected.
7) Take a look at your old app/assets/javascripts/application.js file and compare it to the new file. Ensure that the new file has the jquery ujs library included //= require jquery_ujs . Without this bit of magic your PUT and DELETE HTTP verbs won't work properly.
8) Path adjustments. My theme had the Font Awesome library included. In order to get it to work, I had to adjust the reference paths at the top of the font-awesome.scss file.
9) Finally, you'll need to debug the newly added code in the environment.rb file. The Sinatra developer was doing a lot of Route magic to adjust the navigation display. This wasn't porting over well to my environment. I removed many of these calls from my navigation template files. Once complete, my newly skinned app was up and running! Good luck.
make sure that while installing twitter bootstrap you should add following gem into your Gemfile under "group :assets"
gem 'therubyracer'
gem 'less-rails'
gem 'twitter-bootstrap-rails'
then run bundle command.
Now, the theme "file_name.css" (file_name could be any) that u have downloaded just add it into "stylesheets" folder under app->assests->stylesheets
then open your application.css file in same folder there you will see
*= require_tree.
replace this line with
*= require "file_name.css"
NOTE: Don't forget to re-compile your assets or simply delete the content of your tmp/cache folder.
save it and reboot your server. it will apply youe new theme.
Watch this training course which guide you to do so in detail and from scratch.
http://pluralsight.com/training/courses/TableOfContents?courseName=getting-started-aspdotnet-mvcservice-stack-bootstrap

Is there a "Rails Way" to fold a Twitter Bootstrap theme into a Rails 3 application?

I purchased a nice-looking Twitter Bootstrap them online that is going to spice up my Rails 3.2.8 application. The package contains the following directories:
/css
/img
/js
Of course these files will have relative links to each other in them. Is there a standard way of integrating this type of stuff into the asset pipeline, or is it still a standard practice to put it under public?
You'll want to use the asset pipeline. Everything is moving that direction and it's really not any harder (except when it is). Your files will go in the /app/assets/ directory.
For the css, you should be able to drop it right into app/assets/stylesheets/, just be sure that bootstrap is included first. There are several gems that make it easy to include bootstrap's files. I use bootstrap-sass, but you might also try twitter-bootstrap-rails (depends on if you want sass support or not). With either one, look at the readmes that I linked to as they include some useful details you'll want to know for each gem.
For the javascript, it should be about the same thing. In your application.js file, be sure that bootstrap is include before //= require_tree . in case the theme adds any custom javascript. Both of the gems I listed before also include the javascript files for bootstrap. You can read their documentation to see the details (it's almost exactly the same as normal for both gems).
As far as images are concerned, put them in the app/assets/images/ directory and you'll have to change the stylesheets a bit for it to work. When an image is declared in the stylesheet, like background: url('./images/bg.jpg');, you'll need to use the image_path helper instead, so it would look like background: url(image_path('bg.jpg'));. Notice I just included the name of the image. The asset pipeline will automatically parse this to the correct path for you.
If the theme includes any custom fonts, you'll do the same as images except using the asset_path helper like so in your #font-face declaration:
url(asset-path('museo700.ttf', font));
There are also type-specific helpers you can use, such as font-path, image-path, etc. Either asset-path with a type declared or the type-specific helper will work, just be consistent with which one you use so as not to produce confusion.
You can place custom fonts in a directory something like app/assets/fonts/. The asset pipeline will automatically find them, since they're in the assets directory.

Ways to organise CSS in Rails project

I would like to know what are the best ways to organise CSS code in Rails project?
I'm interested in how you do it and why.
If you would like to break up your css into multiple files during development you can add cache => true to stylesheet_link_tag and rails will automatically concatenate them into a single file in production. This also works for javascript_include_tag.
http://guides.rubyonrails.org/layouts_and_rendering.html#linking-to-javascript-files-with-javascript_include_tag
Generally, you should not have the client download a massive amount of CSS snippets, but pack them into a single file on the server to avoid rendering latencies. So you have the tradeoff of having functionality divided up into multiple files put wanting to send only one file to the client.
You could use SASS to have each piece of code inside a single include file and just include all of them together. This gives you the added advantage of mixins (kind of like macros) and variables among other awesome things.
Another possibility would be to use plain CSS and use something like Jammit to pack the stuff up to send to the client.
Regarding actual setups, I tend to have one file resetting the styles to a known default, a file for the basic layout (columns, default spaces, ...), and one file each for each area of concern for your specific design (headers, buttons, ...)
James and Holger's answers are very good.
Besides organizing CSS in my projects, I also had to change colour schemes a couple of times..
Trying to do consistent changes throughout many CSS files can be pretty painful (results may vary).
I ended up extending the Rails start-up procedure a little, to include a custom module "site_settings.rb"
through which I can define variable for colors and other CSS attributes, which I can then use throughout my CSS input files.
Whenever Rails starts up, and one of the input files has changed, it auto-generates the CSS files.
http://unixgods.org/~tilo/Ruby/Using_Variables_in_CSS_Files_with_Ruby_on_Rails.html
Since Rails 3.1 is out and sprockets replaced Jammit, here an excerpt form the Rails guides concerning the asset organization:
Asset Organization
Assets can be placed inside an application in one of three locations: app/assets, lib/assets or vendor/assets.
app/assets is for assets that are owned by the application, such as custom images, JavaScript files or stylesheets.
lib/assets is for your own libraries’ code that doesn’t really fit into the scope of the application or those libraries which are shared across applications.
vendor/assets is for assets that are owned by outside entities, such as code for JavaScript plugins.

Resources