Arquivo da categoria: Rails

Criando um CRUD com Angular 2 + Rails 5

Introdução ?

Os Apps profissionais seguem há algum tempo na direção de ter uma divisão entre o backend (API) e o front end (Cliente Web), recentemente foi lançado a versão 2 do Angular (que tem pouco a ver com a versão 1) e também a versão 5 do Rails (que tem muito a ver com a versão 4 ? ), nesse tutorial eu vou demonstrar como conectar essas duas tecnologias para criar um App incrível \o/.

Nós vamos criar um CRUD de uma pequena aplicação de FAQ, e para fazer isso mais rapidamente nós vamos usar uma ferramenta bem legal que chama Angular-CLI (command line interface), que vai nos permitir gerar o projeto Angular 2, os components e os services facilmente (similar aos generates do Rails).

O que vamos aprender?
  1. Como criar um CRUD em uma aplicação Rails 5
  2. Como criar um CRUD em uma aplicação Angular 2
  3. Como conectar o Rails 5 com o Angular 2
INGREDIENTES
Objetivos

Criar um Pequeno App que nos permita criar questões para um FAQ, com o front end em Angular 2 e o Backend no Rails 5.

Passo a Passo
  • Rails 5
    1. Criar o Projeto Rails Api
    2. Gerar o CRUD
    3. Incluir o CORS
  • Angular 2
    1. Criar o Projeto Angular usando o Angular-CLI
    2. Configurar nosso projeto
    3. Criar nossos components
    4. Criar nosso service
    5. Editar nossas views
    6. Conectar tudo isso ?
Mãos à Obra \o/
Parte 1 – Criando o projeto Rails 5

Primeiro vamos gerar o nosso projeto Rails 5 API que vai ser consumido via JSON pelo projeto Angular 2.

  1. Para começar, rode no seu console o comando para gerar o projeto:

    *a flag –api significa que o rails vai configurar o projeto como uma API pra gente

  2. Agora vamos gerar nosso scaffold, rode:
  3. Rode as migrations:
  4. Agora vamos configurar o CORS para que nosso APP possa receber chamada de outros domínios, primeiro no seu Gemfile adicione:

    *O que é CORS

  5. Rode o bundle, para instalar a Gem:
  6. Agora no arquivo config/application.rb, substitua o conteúdo por:
  7. Para testar, rode o servidor e visite http://localhost:3000/questions
  8. Pronto \o/, nossa aplicação Rails já está pronta. Agora vamos para o Angular 2 ?

 

Pausa para o Merchan do BEM! ?
BOOTCAMP ONE BIT CODE – SUBA DE LEVEL NO MUNDO DO RUBY ON RAILS

Este é o último final de semana para se inscrever no primeiro Bootcamp online do OneBitCode!
Neste curso, nós vamos criar do zero um site similar ao Airbnb usando Rails 5 como Api e Angular 2 como cliente Web.
O curso vai ter vídeo aulas semanais, live de 2 horas por semana, suporte total às dúvidas e um Slack exclusivo para os alunos desenvolverem network.
O curso vai ser ÉPICO, então confere a Landing Page dele e faça parte do grupo de alunos One Bit Code! \o/
Conheça o Bootcamp!

Parte 2 – Criando o App Angular 2

Agora sim começa a parte mais emocionante complicada, vamos criar nosso APP Angular 2 e para fazer isso vamos usar o Angular-CLI.

Dependências

Primeiro, vamos começar com as dependências.

  1. Você vai precisar ter o NPM instalado na sua máquina. Para instalar no Ubuntu:

    Para instalar no Mac:

  2. Agora você precisa instalar o Angular-CLI:
Criação do App

Finalmente, vamos a criação do App.

  1. Para gerar o projeto, rode na pasta desejada (fora do projeto Rails) no console:
  2. Agora vamos ver se tudo funcionou corretamente, dentro do projeto, rode no console:
  3. Acesse no seu browser, http://localhost:9000, deve aparecer uma mensagem dizendo que funcionou ?
  4. Agora vamos gerar nossos components, rode:

    *Os components são o coração do Angular 2, eles são a principal maneira que nós criamos elementos, definimos as views e a lógica

  5. Depois rode:
  6. Agora vamos gerar nosso Modelo de dados, crie uma pasta no caminho “/src/app/questions/” com o nome shared (“/src/app/questions/shared”).
  7. Depois crie um arquivo dentro dessa pasta chamado “question.ts” e coloque o seguinte conteúdo:
  8. Vamos criar nosso Service (ele serve para o Angular 2 conversar com a API), no console rode o comando:
  9. Agora vamos adicionar o router outlet para fazer nossas rotas funcionarem, no nosso arquivo ‘src/app/app.componet.html’ substitua o conteúdo por:
  10. Agora nós vamos criar o nosso arquivo de rotas (que vai gerenciar nossas URLs), no caminho “src/app/” crie o arquivo “app.routing.ts” e preencha ele com o seguinte conteúdo:
    *Note os comentários no código

  11. Agora nós precisamos alterar nosso arquivo ‘src/app/app.module.ts’ para incluir nosso arquivo de rotas e algumas dependências do projeto, seu arquivo deve ficar assim:
    *Note os comentários no código

  12. Agora nós vamos editar nossos components, para começar vamos editar nosso componente de listagem, no arquivo ‘/src/app/questions/questions.component.ts’ substitua o conteúdo por:
    *Note os comentários no código

  13. Pronto, a parte lógica da listagem está ok (exceto pelo service ainda), agora vamos editar a aparência da aplicação, no arquivo ‘/src/app/questions/questions.component.html’ adicione o seguinte html:
  14. Agora vamos para o próximo component, no arquivo /src/app/questions/question-form/question-form.component.ts’ cole o seguinte código para podermos editar e criar questions:
    *Note os comentários no código

  15. Pronto, a parte lógica da edição/criação está ok (exceto pelo service ainda), agora vamos editar a aparência da aplicação, no arquivo ‘/src/app/questions/question-form/question-form.component.html’ adicione o seguinte html:
  16. Excelente, nossos components estão ok, agora vamos configurar nosso service. No arquvio ‘src/app/questions/shared/questions.service.ts’ susbstitua o conteúdo pelo seguinte código:
    *Note os comentários no código

  17. Pronto \o/, agora vamos testar.
  18. Rode no seu console:
  19. Acessando no browser, seu resultado deve ser similar a este:
    captura-de-tela-de-2016-12-10-02-49-37* É claro que não é um Faq muito bonito, mas ele funciona e é suficiente para demonstrar a integração ?
  20. Agora você pode criar novas questões, editá-las e deletá-las \o/, parabéns nós conseguimos!

 

CONCLUSÃO

Pronto, conseguimos fazer o nosso não tão simples CRUD, mas valeu a pena :). É claro que esse é um tutorial introdutório apenas para te dar uma visão geral de como o Angular 2 e o Rails 5 podem se comunicar e também para abrir um pouco a sua mente para a estrutura do Angular 2. Mas tenho certeza que você notou a riqueza dos dois frameworks e as possibilidades ilimitadas que eles trazem se usados juntos ?

Como de costume o Código completo da aplicação está no Github, caso você queria clonar o código, clique aqui para ver a parte do Angular 2 e clique aqui para acessar a parte do Rails 5. Aproveita e me segue lá \o/

Apenas informando novamente que o Bootcamp do OneBitCode está com as inscrições abertas (quase fechando já) e nesse bootcamp nós vamos nos aprofundar muito no Rails 5 e também no Angular 2 (fullstack) através da criação de um clone do Airbnb, então se você ainda não viu a landing page, VEJA CLICANDO AQUI. Vai ser épico, não deixe essa chance passar! \o/

Se você ficou com dúvidas ou tem sugestões de posts para o Blog comenta aí em baixo ou me adiciona no Facebook clicando aqui.

 

Share and Enjoy !

0Shares
0 0

Rails – How to convert PDF to Excel or CSV

In Rails 4:

require 'httmultiparty'
class PageTextReceiver
  include HTTMultiParty
  base_uri 'http://localhost:3000'

  def run
    response = PageTextReceiver.post('https://pdftables.com/api?key=myapikey', :query => { f: File.new("/path/to/pdf/uploaded_pdf.pdf", "r") })

    File.open('/path/to/save/as/html/response.html', 'w') do |f|
      f.puts response
    end
  end

  def convert
    f = File.open("/path/to/saved/html/response.html")
    doc = Nokogiri::HTML(f)
    csv = CSV.open("path/to/csv/t.csv", 'w',{:col_sep => ",", :quote_char => '\'', :force_quotes => true})
    doc.xpath('//table/tr').each do |row|
      tarray = []
      row.xpath('td').each do |cell|
        tarray << cell.text
      end
      csv << tarray
    end
    csv.close
  end
end

http://stackoverflow.com/questions/30183738/how-to-convert-pdf-to-excel-or-csv-in-rails-4

Share and Enjoy !

0Shares
0 0

Rails4 Autocomplete

https://github.com/peterwillcn/rails4-autocomplete

rails4-autocomplete

An easy way to use jQuery’s autocomplete with Rails 4.

Supports both ActiveRecord, mongoid, and MongoMapper.

Works with Formtastic and SimpleForm

Before you start

Make sure your project is using jQuery-UI and the autocomplete widget before you continue.

You can find more info about that here:

I’d encourage you to understand how to use those 3 amazing tools before attempting to use this gem.

Demo Application rails4-autocomplete-demo

A live demo can be seen

here

source.

As a new developer, I had some issues getting this to work by following the documentation. However after trying some things and reading Yoni Weisbrod‘s blog post, I was able to make the autocomplete work and implement a few useful features.

Installing

Include the gem on your Gemfile

gem 'rails4-autocomplete'

Install it

bundle install

Rails 3.0.x

Run the generator

rails generate autocomplete:install

And include autocomplete-rails.js on your layouts

javascript_include_tag "autocomplete-rails.js"

Upgrading from older versions

If you are upgrading from a previous version, run the generator after installing to replace the javascript file.

rails generate autocomplete:install

I’d recommend you do this every time you update to make sure you have the latest JS file.

Uncompressed Javascript file

If you want to make changes to the JS file, you can install the uncompressed version by running:

rails generate autocomplete:uncompressed

Rails 4.x

Just add it to your app/assets/javascripts/application.js file

//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require autocomplete-rails

Usage

Model Example

Assuming you have a Brand model:

class Brand < ActiveRecord::Base
end

create_table :brand do |t|
  t.column :name, :string
end

Controller

To set up the required action on your controller, all you have to do is call it with the class name and the method as in the following example:

class ProductsController < Admin::BaseController
  autocomplete :brand, :name
end

This will create an action autocomplete_brand_name on your controller, don’t forget to add it on your routes file

resources :products do
  get :autocomplete_brand_name, :on => :collection
end

Options

:full => true

By default, the search starts from the beginning of the string you’re searching for. If you want to do a full search, set the full parameter to true.

class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :full => true
end

The following terms would match the query ‘un’:

  • Luna
  • Unacceptable
  • Rerun

:full => false (default behavior)

Only the following terms mould match the query ‘un’:

  • Unacceptable

:extra_data

By default, your search will only return the required columns from the database needed to populate your form, namely id and the column you are searching (name, in the above example).

Passing an array of attributes/column names to this option will fetch and return the specified data.

class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :extra_data => [:slogan]
end

:display_value

If you want to display a different version of what you’re looking for, you can use the :display_value option.

This options receives a method name as the parameter, and that method will be called on the instance when displaying the results.

class Brand < ActiveRecord::Base
  def funky_method
    "#{self.name}.camelize"
  end
end


class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :display_value => :funky_method
end

In the example above, you will search by name, but the autocomplete list will display the result of funky_method

This wouldn’t really make much sense unless you use it with the “id_element” attribute. (See below)

Only the object’s id and the column you are searching on will be returned in JSON, so if your display_value method requires another parameter, make sure to fetch it with the :extra_data option

:scopes

Added option to use scopes. Pass scopes in an array. e.g :scopes => [:scope1, :scope2]

:column_name

By default autocomplete uses method name as column name. Now it can be specified using column_name options:column_name => 'name'

json encoder

Autocomplete uses Yajl as JSON encoder/decoder, but you can specify your own

class ProductsController < Admin::BaseController
  autocomplete :brand, :name do |items|
     CustomJSON::Encoder.encode(items)
  end
end

View

On your view, all you have to do is include the attribute autocomplete on the text field using the url to the autocomplete action as the value.

form_for @product do |f|
  f.autocomplete_field :brand_name, autocomplete_brand_name_products_path
end

This will generate an HTML tag that looks like:

<input type="text" data-autocomplete="products/autocomplete_brand_name">

If you are not using a FormBuilder (form_for) or you just want to include an autocomplete field without the form, you can use the autocomplete_field_tag helper.

form_tag 'some/path'
  autocomplete_field_tag 'address', '', address_autocomplete_path, :size => 75
end

Multiple Values Separated by Delimiter

To generate an autocomplete input field that accepts multiple values separated by a given delimiter, add the 'data-delimiter' and :multiple options:

form_for @product do |f|
  f.autocomplete_field :brand_names, autocomplete_brand_name_products_path,
  'data-delimiter' => ',', :multiple => true
end

NOTE: Setting the :multiple option to true will result in the chosen values being submitted as an array. Leaving this option off will result in the values being passed as a single string, with the values separated by your chosen delimiter.

Now your autocomplete code is unobtrusive, Rails 3 style.

Getting the object id

If you need to use the id of the selected object, you can use the id_element attribute too:

f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :id_element => '#some_element'

This will update the field with id *#some_element with the id of the selected object. The value for this option can be any jQuery selector.

Getting extra object data

If you need to extra data about the selected object, you can use the :update_elements HTML attribute.

The :update_elements attribute accepts a hash where the keys represent the object attribute/column data to use to update and the values are jQuery selectors to retrieve the HTML element to update:

f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :update_elements => {:id => '#id_element', :slogan => '#some_other_element'}

class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :extra_data => [:slogan]
end

The previous example would fetch the extra attribute slogan and update jQuery(‘#some_other_element’) with the slogan value.

Running custom code on selection

A javascript event named railsAutocomplete.select is fired on the input field when a value is selected from the autocomplete drop down. If you need to do something more complex than update fields with data, you can hook into this event, like so:

$('#my_autocomplete_field').bind('railsAutocomplete.select', function(event, data){
  /* Do something here */
  alert(data.item.id);
});

Custom message when not results are found

You can pass a custom message for when there is not results found. For this the element must have a data attribute named data-autocomplete-label. For example:

autocomplete_field_tag 'address', '', address_autocomplete_path, :size => 75, 
:"data-autocomplete-label" => "Sorry, nothing found."

Formtastic

If you are using Formtastic, you automatically get the autocompleted_input helper on semantic_form_for:

semantic_form_for @product do |f|
  f.input :brand_name, :as => :autocomplete, :url => autocomplete_brand_name_products_path
end

The only difference with the original helper is that you must specify the autocomplete url using the :url option.

SimpleForm

If you want to use it with simple_form, all you have to do is use the :as option on the input and set the autocomplete path with the :url option.

simple_form_for @product do |form|
  form.input :name
  form.input :brand_name, :url => autocomplete_brand_name_products_path, :as => :autocomplete

Cucumber

I have created a step to test your autocomplete with Cucumber and Capybara, all you have to do is add the following lines to your env.rb file:

require 'cucumber/autocomplete'

Then you’ll have access to the following step:

I choose "([^"]*)" in the autocomplete list

An example on how to use it:

@javascript
Scenario: Autocomplete
  Given the following brands exists:
    | name  |
    | Alpha |
    | Beta  |
    | Gamma |
  And I go to the home page
  And I fill in "Brand name" with "al"
  And I choose "Alpha" in the autocomplete list
  Then the "Brand name" field should contain "Alpha"

I have only tested this using Capybara, no idea if it works with something else, to see it in action, check the example app.

Steak

I have created a helper to test your autocomplete with Steak and Capybara, all you have to do is add the following lines to your acceptance_helper.rb file:

require 'steak/autocomplete'

Then you’ll have access to the following helper:

choose_autocomplete_result

An example on how to use it:

scenario "Autocomplete" do
  lambda do
    Brand.create! [
      {:name => "Alpha"},
      {:name => "Beta"},
      {:name => "Gamma"}
    ]
  end.should change(Brand, :count).by(3)

  visit home_page
  fill_in "Brand name", :with => "al"
  choose_autocomplete_result "Alpha"
  find_field("Brand name").value.should include("Alpha")
end

I have only tested this using Capybara, no idea if it works with something else.

Development

If you want to make changes to the gem, first install bundler 1.0.0:

gem install bundler

And then, install all your dependencies:

bundle install

Running the test suite

You need to have an instance of MongoDB running on your computer or all the mongo tests will fail miserably.

To run all the tests once, simply use

rake test

while you’re developing, it is recommended that you run

bundle exec guard

to have the relevent test run every time you save a file.

Integration tests

If you make changes or add features to the jQuery part, please make sure you write a cucumber test for it.

You can find an example Rails app on the integration folder.

You can run the integration tests with the cucumber command while on the integration folder:

cd integration
rake db:migrate
cucumber

Where to test what

If you’re making or tweaking a plugin (such as the formastic plugin or simple_form plugin), check out the simple_form_plugin_test for an example of how to test it as part of the main rake test run. Historically, plugins like these had been tested (shoddily) as part of the integration tests. Feel free to remove them from the integration suite and move them into the main suite. Your tests will run much faster, and there will be less likelihood of your feature breaking in the future. Thanks!

Share and Enjoy !

0Shares
0 0