quarta-feira, 15 de janeiro de 2014

Ruby - How to Create GEMS

How to Create GEMS
    Very simple to create a GEM
    1. Create the directory structure
    .
    --- Rakefile
    --- bin
         --- hello_anderson
    --- hello_anderson.gemspec
    --- lib
         --- hello_anderson.rb
    --- test
         --- test_hello_anderson.rb

        Inside lib it is necessary to have a rb file with the same name of the GEM.
        Ex:
            class HelloAnderson
              def self.say_hello
                puts "Hello Anderson!"
              end
            end

    hello_anderson.gemspec is responsible for model the gem.  Inside it we have what the gem is and its version. 
    Ex:
        Gem::Specification.new do |s|
          s.name        = 'hello_anderson'
          s.version     = '0.0.0'
          s.date        = '2013-12-12'
          s.summary     = "Hellow Anderson!"
          s.description = "Example of a gem saing hello to Anderson"
          s.authors     = ["Anderson Araujo Lopes"]
          s.email       = 'romalopes@yahoo.com.br'
          s.files       = ["lib/hello_anderson.rb", other files...]
          s.homepage    =
            'http://rubygems.org/gems/hello_anderson'
          s.license       = 'MIT'
        end

    To build a GEM
        $ gem build hello_anderson.gemspec
    To install a GEM
        $ gem install ./hello_anderson-0.0.0.gem

    To use a GEM
        use: require "hello_anderson"
                HelloAnderson.say_hello

    The published geuemms are in:
        http://rubygems.org/
        Process:
        1. To setup the computer with your RubyGems account:
            $ curl -u qrush https://rubygems.org/api/v1/api_key.yaml >
~/.gem/credentials; chmod 0600 ~/.gem/credentials
        2 . gem push hello_anderson-0.0.0.gem

    To see the GEM in rubygems.org
        $ gem list -r hello_anderson
    To install the GEM from rubygems.org
        $ gem install hola

Adding a executable
    place the file bin/hello_anderson
    chmod a+x bin/hello_anderson

    #!/usr/bin/env ruby

    require 'hello_anderson'
    puts Hola.say_hello()


    To run the GEM
        $ ruby -Ilib ./bin/hello_anderson

    Test
        Fill Rakefile
            require 'rake/testtask'
            Rake::TestTask.new do |t|
              t.libs << 'test'
            end

            desc "Run tests"
            task :default => :test

        Fill test/test_hello_anderson.rb
            require 'test/unit'
            require 'hello_anderson'

            class HelloAndersonTest < Test::Unit::TestCase
              def test_hello_anderson
                assert_equal "Hello Anderson", HelloAnderson.say_hello
              end
            end

        run test
            $ rake test
            OR
            $ rake

    Document
        Gems use RDoc to generate docs


Ruby on Rails-Action Mailer Basics

====
   Based on guides.rubyonrails.org

Action Mailer Basics
    Send eails using mailer classes and views
    Class inherit from ActionMailer::Base and live in app/mailers
    Mailers are conceptually similar to controllers
    Steps
    1. Create the mailer
        $ rails generate mailer UserMailer
        user_mailer.rb created
            class UserMailer < ActionMailer::Base
              default from: 'from@example.com'      <-- br="" default="" from="">            end
    2. It is possible jusst to create the Mailer in app/mailers
        class MyMailer < ActionMailer::Base
        end
    3. Add a method called welcome
         def welcome_email(user)
            @user = user
            @url  = 'http://example.com/login'
            mail(to: @user.email, subject: 'Welcome to My Awesome Site')
         end
    4. Create the views/user_mailer/welcome.html.erb
       
       
         
           
         
         
           

Welcome to example.com, <%= @user.name %>


           
              You have successfully signed up to example.com,
              your username is: <%= @user.login %>.

           

           
              To login to the site, just follow this link: <%= @url %>.
           

            Thanks for joining and have a great day!

         
       
        4.1 It is possible to create a text(non html) file too. welcome_email.text.erb
    With method webcome_email, rails will automatically render both html and text files.
    5. In method create of UsersController
          if @user.save
            # Tell the UserMailer to send a welcome Email after save
            UserMailer.welcome_email(@user).deliver


Ruby on Rails-Working with JavaScript in Rails

====
   Based on guides.rubyonrails.org




Working with JavaScript in Rails
    Unobtrusive JavaScript
        Jaav uses a "Unobtrusive javaScript" technique
        EX:

            < a href="#" data-background-color="#990000">Paint it red< /a>


            data-background is called in unobtrusive way because there is no mix between JavaScript and HTML
        Call:
            paintIt = (element, backgroundColor, textColor) ->
              element.style.backgroundColor = backgroundColor
              if textColor?
                element.style.color = textColor
           
            $ ->
              $("a[data-background-color]").click ->
                backgroundColor = $(this).data("background-color")
                textColor = $(this).data("text-color")
                paintIt(this, backgroundColor, textColor)
    Built-in Helpers
        Many view helper methods to assist generating HTML.

        form_for
            <%= form_for(@post, remote: true) do |f| %>
              ...
            <% end %>
        form_tag
            <%= form_tag('/posts', remote: true) %>
        link_to
            <%= link_to "a post", @post, remote: true %>

            <%= link_to "Delete post", @post, remote: true, method: :delete %>

            in CoffeScript, uses
                $ -> $("a[data-remote]").on "ajax:success", (e, data, status, xhr) -> alert "The post was deleted."
            or in directly
                <%= link_to "delete", account, method: :delete, data: { confirm: "You sure?" } %>
        button_to
            <%= button_to "A post", @post, remote: true %>
    The server side
        Usually, AJAX requests return JSON rather than HTML
            Controller
                class UsersController < ApplicationController
                  def index
                    @users = User.all
                    @user = User.new
                  end
                  def create
                      @user = User.new(params[:user])
                   
                      respond_to do |format|
                        if @user.save
                          format.html { redirect_to @user, notice: 'User was successfully created.' }
                          format.js   {}
                          format.json { render json: @user, status: :created, location: @user }
                        else
                          format.html { render action: "new" }
                          format.json { render json: @user.errors, status: :unprocessable_entity }
                        end
                      end
                    end
            index.html.erb
                < b >Users< /b >
   
                < ul id="users">  <----- appendto="" br="" fill="" here="" in="" js="" the="" will="">                    <% @users.each do |user| %>
                      <%= render user %>   <----- _user.html.erb="" br="" render="" the="">                    <% end %>
                < /ul >
               
                < br>
               
                <%= form_for(@user, remote: true) do |f| %>
                  <%= f.label :name %>

                  <%= f.text_field :name %>
                  <%= f.submit %>
                <% end %>
            _user.html.erb
                < li ><%= user.name %>< /li >
            create.js.erb
                It is called by the method create.
                $("<%= escape_javascript(render @user) %>").appendTo("#users");
    Turbolinks
        Uses AJAX to speed up page rendering in most applications
        It attaches a click handler to all < a > tags
        What to do
            Include turbolinks in Gemfile
            in app/assets/javascripts/application.js
                //= require turbolinks
            To disable turbolink
                < a href="..." data-no-turbolink>No turbolinks here< /a>.


terça-feira, 14 de janeiro de 2014

Ruby on Rails-Rails Routing from the Outside In

====
   Based on guides.rubyonrails.org

Rails Routing from the Outside In

    The Purpose of the Rails Router
        Simple example:
                                GET /patients/17
                    Route
                                get '/patients/:id', to: 'patients#show'

        Or
                    get '/patients/:id', to: 'patients#show', as: 'patient'
                    and your application contains this code in the controller:
                                @patient = Patient.find(17)
                    and this in the corresponding view:
                                <%= link_to 'Patient Record', patient_path(@patient) %>
                    Route will generate
                                /patients/17
        CRUD, Verbs, and Actions
            If declare
                resources :photos
                If creates 7 routes
                    HTTP        Verb             Path
                    GET        /photos             index  
                    GET        /photos/new      new
                    POST           /photos         create 
                    GET        /photos/:id         show  
                    GET        /photos/:id/edit edit     
                    PATCH/PUT  /photos/:id      update
                    DELETE     /photos/:id      destroy
            Singular resources
                To call
                    /profile
                route
                    get 'profile', to: 'users#show'

    A singular resourceful route generates these helpers:
        new_photo_path returns / photo /new
        edit_ photo _path returns / photo /edit
        photo _path returns / photo
        Controller Namespaces and routing
            It is possible to organize groups of controllers under a namespace
            EX:
            namespace : admin do
                            resources :posts, :comments
            end
            It will create routes for post and comments .  For Admin::PostController
                GET /admin/posts              admin_post_path
                GET /admin/posts/new         new_admin_post_path
                POST /admin/posts/:id       admin_post_path(:id)
                etc
            Uses Admin::PostController without the prefix /admin, just declares:
                scope module: ‘admin’ do
                    resources :posts, :comments   
                end
                OR
                resources :posts, module:’admin’

            To use /admin/post without  admin in path.
                Scope ‘/admin’ do
                                Resources :posts, :comments
                End
            Resources :posts, path: ‘/admin/posts’
                GET /admin/posts                           posts_path
                GET /admin/posts/new                                new_post_path
                Nested Resources
    when there are resources that are children of others.
        Models:
            class Magazine < ActiveRecord::Base
                  has_many
                    :ads
                end
             end
            class Ad < ActiveRecord::Base
                  belongs_to :magazine
            end
            Resources:
                resources :magazines do
                      resources :ads
                end
            /magazines/:magazine_id/ads
            /magazines/:magazine_id/ads/new
            /magazines/:magazine_id/ads
            The url: edit_magazine_ad_path
            It is possible to nest 2 levels
   
        resources :publishers do
          resources :magazines do
            resources :photos
          end
        end
        Calling:
            /publishers/1/magazines/2/photos/3
    Paths and URLs From Objects
        resources :magazines do
          resources :ads
        end
        You can pass instances of magazines and ads
            <%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
        Or
            <%= link_to 'Ad details', url_for([@magazine, @ad]) %>
            Or
            <%= link_to 'Ad details', [@magazine, @ad] %>
            Rails will se magazines and ads and create the path.
        To call Edit
        <%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>
    Adding More RESTful Actions
        Add Member Routes
            resources :photos do
              member do
                get 'preview'
              end
            end
            Provides:   
            GET     /photos/1/preview
            and preview_photo_url and preview_photo_path helpers

segunda-feira, 2 de dezembro de 2013

Ruby on Rails-Action Controoler Overview

====
   Based on guides.rubyonrails.org


Controller is the C from MVC
Controller Name
                Preferable in plural: ClientsController
Methods and Actions
                Normal ruby class the inherits from ApplicationController
                Ex  /clients/new:
                               class ClientsController < ApplicationController
                                 def new
                                               @client = Client.new
                                 end
                               end       
Parameters
                Rails doesn't make any distinction between GET or POST parameters
                # In the example:
                def create
                    @client = Client.new(params[:client])
                    if @client.save
                      redirect_to @client
                    else
                      # This line overrides the default rendering behavior, which
                      # would have been to render the "create" view.
                      render "new"
                    end
                end
                # Values came from
           <form accept-charset="UTF-8" action="/clients" method="post">  

            <input type="text" name="client[name]" value="Acme" />
            <input type="text" name="client[phone]" value="12345" />
            <input type="text" name="client[address][postcode]" value="12345" />
            <input type="text" name="client[address][city]" value="Carrot City" />
           </form>
                             

                JSON parameters
                               If working with JSON, Rails convert automatically the parameters in parms hash.
Routing parameters
                Hash params always contains :controller and :action keys
Strong parameters
                Action Controller parameters can be used in Active Model mass assigments only after they pass through another method(whitelisted).  The params will be chosen to be exposed.
                Ex:
                               class PeopleController < ActionController::Base
                                               def update
                                                   person = current_account.people.find(params[:id])
                                                   person.update_attributes!(person_params)
                                                               redirect_to person
                                                               end
                                                               private
                                   def person_params
                                     params.require(:person).permit(:name, :age)
                                   end
                               end
Session
                Kinds of session:
                               ActionDispatch::Session::CookieStore - Stores everything on the client.
                               ActionDispatch::Session::CacheStore - Stores the data in the Rails cache.
                               ActionDispatch::Session::ActiveRecordStore - Stores the data in a database using Active Record. (require activerecord-session_store gem).
                               ActionDispatch::Session::MemCacheStore - Stores the data in a memcached cluster

                If you need a different session storage mechanism, you can change it in the config/initializers/session_store.rb file.
                ex:
                               RomaMoneyRails::Application.config.session_store :cookie_store, key: '_romaMoneyRails_session', domain: ".example.com"
                               #domain is optional
                CookieStore used for signing the session data
                               Can be changed in  config/initializers/secret_token.rb:
                               EX, create a random value:
                                               require 'securerandom'

                                               def secure_token
                                                 token_file = Rails.root.join('.secret')
                                                 if File.exist?(token_file)
                                                   # Use the existing token.
                                                   File.read(token_file).chomp
                                                 else
                                                   # Generate a new token and store it in token_file.
                                                   token = SecureRandom.hex(64)
                                                   File.write(token_file, token)
                                                   token
                                                 end
                                               end
                                               RomaMoneyRails::Application.config.secret_key_base = secure_token
                Accessing Session
                               def current_user
                                   @_current_user ||= session[:current_user_id] &&
                                     User.find_by(id: session[:current_user_id])
                               end

                               def create
                                   if user = User.authenticate(params[:username], params[:password])
                                     # Save the user ID in the session so it can be used in
                                     # subsequent requests
                                     session[:current_user_id] = user.id
                                     redirect_to root_url
                                   end
                               end                                      

                               To reset the intire session:
                                               reset_session
                Flash
                               Special part of session that is cleared in each request. It will available only in the next request.              
                               Ex:
                                               flash[:notice] = "You have successfully logged out."
Cookie
                To store cookie is similar to Session
                # Remember the commenter's name.
    cookies[:commenter_name] = @comment.author
Render xml and JSON data

                class UsersController < ApplicationController
                  def index
                    @users = User.all
                    respond_to do |format|
                      format.html # index.html.erb
                      format.xml  { render xml: @users} # automatically invokes @users.to_xml
                      format.json { render json: @users}
                    end
                  end
                end
Render JSON with JavaScript
                 @user = User.first
                 respond_to do |format|
                               format.html { redirect_to root_url }
                               format.js
     end
     Should have a file js.erb with the same name of the action
Filter
                Runs before, after or "arround" the controller action
                There are different ways to access Filters, but these are the most known ones
                before_action
                Ex:
                               class ApplicationController < ActionController::Base
                                                 before_action :require_login
                                                  private

                                                 def require_login
                                                   unless logged_in?
                                                     flash[:error] = "You must be logged in to access this section"
                                                     redirect_to new_login_url # halts request cycle
                                                   end
                                                 end
                                               end

                                               - this will be run on every controller
                               Ex of before_action for user_controller.rb
                                               before_action :signed_in_user,
                only: [:index, :edit, :update, :destroy, :change_to_this, :change_account, :change_account_ajax]
                                               before_action :correct_user,   only: [:edit, :update]
                                               before_action :admin_user,     only: :destroy

                               Skiping before for some methods
                                               class LoginsController < ApplicationController
                                                 skip_before_action :require_login, only: [:new, :create]
                                               end
                after_action
                               After is similar to before. 
                               Has access to response.
                               Can't stop the action
                arround_action
                               Run the associated actions by yielding
Request Forgery Protection
                First step to protect destructive actions from forgery it prohibit GET requests(REST already does this)
Request and Response objects
                Request Object
                               query_parameters - sent as part of the query string
                               request_parameters - sent as part of the post body
                               path_parameters - parameters that were recognized by the routing as being part of the path leading to this particular controller and action.
                Response Object
                               response.headers["Content-Type"] = "application/pdf"
HTTP Authentications
                Basic Authentication
                               Very simple
                               class AdminsController < ApplicationController
                                 http_basic_authenticate_with name: "humbaba", password: "5baa61e4"
                               end
                Digest Authentication
                                only requires using one method, authenticate_or_request_with_http_digest
Streaming and File Downloads
                send_data
                               To stream data to the client, use send_data:
                               Ex:
                                               #Generate a stream and send it
                                               require "prawn"
                                               class ClientsController < ApplicationController
                                                 # Generates a PDF document with information on the client and
                                                 # returns it. The user will get the PDF as a file download.
                                                 def download_pdf
                                                   client = Client.find(params[:id])
                                                   send_data generate_pdf(client),
                                                             filename: "#{client.name}.pdf",
                                                             type: "application/pdf"
                                                 end
                                                
                                                 private
                                                
                                                 def generate_pdf(client)
                                                   Prawn::Document.new do
                                                     text client.name, align: :center
                                                     text "Address: #{client.address}"
                                                     text "Email: #{client.email}"
                                                   end.render
                                                 end
                                               end
                send_file
                               To send a file
                               class ClientsController < ApplicationController
                                 # Stream a file that has already been generated and stored on disk.
                                 def download_pdf
                                   client = Client.find(params[:id])
                                   send_file("#{Rails.root}/files/clients/#{client.id}.pdf",
                                             filename: "#{client.name}.pdf",
                                             type: "application/pdf") #default=application/octet-stream
                                 end
                               end

                               It read 4kb at time avoid loading the entire file to memory at once.  It can be configure.
                RESTFUL download
                               First include in config/initializers/mime_types.rb:
                                               Mime::Type.register "application/pdf", :pdf

                               class ClientsController < ApplicationController
                                 # The user can request to receive this resource as HTML or PDF.
                                 def show
                                   @client = Client.find(params[:id])
                                
                                   respond_to do |format|
                                     format.html
                                     format.pdf { render pdf: generate_pdf(@client) }
                                   end
                                 end
                               end
Log Filtering
                Uses a log file
Rescue
                Useful to send a specific exception to a page
                ex:
                class ApplicationController < ActionController::Base
                  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
                 
                  private
                 
                  def record_not_found
                    render text: "404 Not Found", status: 404
                  end
                end

Force ssl
                In config/environments/production.rb
                               # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
                               config.force_ssl = true
                Of for a specific action and controller
                class DinnerController
                                 force_ssl only: :cheeseburger
                                 # or
                                 force_ssl except: :cheeseburger

                               end

Ruby on Rails-Action View Form Helpers

====
   Based on guides.rubyonrails.org


Most Simple
      use xxx_tag
                <%= form_tag("/search", method: "get") do %>
                  <%= label_tag(:q, "Search for:") %>
                  <%= text_field_tag(:q) %>
                  <%= submit_tag("Search") %>
                <% end %>
      Passing controller and action
                               form_tag(controller: "people", action: "search", method: "get", class: "nifty_form")
                               # => '
'
                                #OR
                                form_tag({controller: "people", action: "search"}, method: "get", class: "nifty_form")
                               # => '
'
Different helpers
      Checkboxs
                <%= check_box_tag(:pet_cat) %>
                <%= label_tag(:pet_cat, "I own a cat") %>
                Result:
                 <input id="pet_cat" name="pet_cat" type="checkbox" value="1" />  
                 <label for="pet_cat">I own a cat</label>  
      RadioBox
                <%= radio_button_tag(:age, "child") %>
                <%= label_tag(:age_child, "I am younger than 21") %>
                Result:
                 <input id="age_child" name="age" type="radio" value="child" />  
                 <label for="age_child">I am younger than 21</label>  

      Others
                <%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
                <%= password_field_tag(:password) %>
                <%= hidden_field_tag(:parent_id, "5") %>
                <%= search_field(:user, :name) %>
                <%= telephone_field(:user, :phone) %>
                <%= date_field(:user, :born_on) %>
                <%= datetime_field(:user, :meeting_time) %>
                <%= datetime_local_field(:user, :graduation_day) %>
                <%= month_field(:user, :birthday_month) %>
                <%= week_field(:user, :birthday_week) %>
                <%= url_field(:user, :homepage) %>
                <%= email_field(:user, :address) %>
                <%= color_field(:user, :favorite_color) %>
                <%= time_field(:task, :started_at) %>
Dealing with Model Objects
      These kind of helpers does not use the sufix "_tag"
      Ex: <%= text_field(:person, :name) %>
      Result: 
 <input id="person_name" name="person[name]" type="text" value="Henry"/>  

      Binding a Form to an Object
                In controller
                               def new
                                 @article = Article.new
                               end
                In view
                               <%= form_for @article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
                                 <%= f.text_field :title %>
                                 <%= f.text_area :body, size: "60x12" %>
                                 <%= f.submit "Create" %>
                               <% end %>
      If I have an association it is possible to define a form to the associated object
                <%= form_for @person, url: {action: "create"} do |person_form| %>
                  <%= person_form.text_field :name %>
                  <%= fields_for @person.contact_detail do |contact_details_form| %>
                    <%= contact_details_form.text_field :phone_number %>
                  <% end %>
                <% end %>
                Result:

                 <form accept-charset="UTF-8" action="/people/create" class="new_person" id="new_person" method="post">  
                  <input id="person_name" name="person[name]" type="text" />  
                  <input id="contact_detail_phone_number" name="contact_detail[phone_number]" type="text" />  
                 </form>  


How do forms with PATCH, PUT, or DELETE methods work?
      Some browsers don't have PATCH, then Rails emulate this method using a hidden parameter in a POST search

      form_tag(search_path, method: "patch")
      results:

         <form accept-charset="UTF-8" action="/search" method="post">  
                                 <div style="margin:0;padding:0">  
                         <input name="_method" type="hidden" value="patch" />  
                         <input name="utf8" type="hidden" value="&#x2713;" />  
                   <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />  
                  </div>  
                  ...  

Select and option
      The simplest way
                <%= select_tag(:city_id, '...') %>
                ex:
                               <%= options_for_select([['Lisbon', 1], ['Madrid', 2], ...]) %>
                Together
                               <%= select_tag(:city_id, options_for_select(...)) %>

                ex:
                               <%= options_for_select([['Lisbon', 1, {'data-size' => '2.8 million'}], ['Madrid', 2, {'data-size' => '3.2 million'}]], 2) %>
                                
                               output:
                                
     <option value="1" data-size="2.8 million">Lisbon</option>  
                 <option value="2" selected="selected" data-size="3.2 million">Madrid</option>  
                     

      Select dealing with model
                # controller:
                               @person = Person.new(city_id: 2)
                # view:
                               <%= select(:person, :city_id, [['Lisbon', 1], ['Madrid', 2], ...]) %>
                               #OR
                               # select on a form builder
                               <%= person.select(:city_id, ...) %>
      Options from a Array or Collection
                <% cities_array = City.all.map { |city| [city.name, city.id] } %>
                <%= options_for_select(cities_array) %>

                #Better
                <%= options_from_collection_for_select(City.all, :id, :name) %>

                All together
                               <%= collection_select(:person, :city_id, City.all, :id, :name) %>
Date and Time
      Barebones Helpers
                select_date, select_time and select_datetime
                <%= select_date Date.today, prefix: :start_date %>

      Equivalent Model Object Helper
                date_select, time_select and datetime_select
                <%= date_select :person, :birth_date %>
                #OR
                <%= person.date_select :birth_date %>
Uploading Files
      The rendered form's encoding MUST be set to "multipart/form-data"
                With form_for it is done automaticaly
                With form_tag, you must set it yourself
                ex:
                <%= form_for @person do |f| %>
                  <%= f.file_field :picture %> -----> params[:picture]
                <% end %>

                <%= form_tag({action: :upload}, multipart: true) do %>
                  <%= file_field_tag 'picture' %> ---->params[:person][:picture]
                <% end %>
      Saving
                Picture is save in #{Rails.root}/public/uploads
                def upload
                  uploaded_io = params[:person][:picture]
                  File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
                                file.write(uploaded_io.read)
                  end
                end
      With ajax
                It is more complex than other forms.
Parameters and conventions
      HTML doesn't have any structured data, just get pairs name-value
      Basic Structure
                               #Input

                         <input id="person_name" name="person[name]" type="text" value="Henry"/>  
                               #Params
                                               {'person' => {'name' => 'Henry'}}

                               #Input

                         <input id="person_address_city" name="person[address][city]" type="text" value="New York"/>  
                               #Params
                                               {'person' => {'address' => {'city' => 'New York'}}}
      Using Form Helper
                <%= form_for @person do |f| %>
                  <%= f.text_field :name %>
                  <% @person.addresses.each do |address| %>
                    <%= f.fields_for address, index: address do |address_form|%>
                      <%= address_form.text_field :city %>
                    <% end %>
                  <% end %>
                <% end %>
                               #Params
                                               {'person' => {'name' => 'Bob', 'address' => {'23' => {'city' => 'Paris'}, '45' => {'city' => 'London'}}}}
      Form to external resources
                # It is possible to pass an external token to access the external resource
                <%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %>
        Form contents
      <% end %>
      # OR
      authenticity_token: false
Complex forms
      #uses accepts_nested_attributes_for
                class Person < ActiveRecord::Base
                  has_many :addresses
                  accepts_nested_attributes_for :addresses
                end
                 
                class Address < ActiveRecord::Base
                  belongs_to :person
                end
                This creates an addresses_attributes= method
      And creates a form with a Person and its associates address
                <%= form_for @person do |f| %>
                  Addresses:
                 
                    <%= f.fields_for :addresses do |addresses_form| %>
                     
  •                         <%= addresses_form.label :kind %>
                            <%= addresses_form.text_field :kind %>
                     
                            <%= addresses_form.label :street %>
                            <%= addresses_form.text_field :street %>
                            ...
                         
                        <% end %>
                                    

                    <% end %>