Ensino Ágil de Programação

Objetivo

Mostrar que o ensino de programação pode ser ministrado de uma forma diferente, tendo sempre como meta a simplicidade e a evolução.

giphy (3)

O que não pretendo

giphy

Transformar você em um programador com apenas este post.  Programar exige, principalmente, interesse e persistência.

Você quer a verdade?

Computadores são estúpidos

tumblr_lf871rVM1H1qe7dux

Isso pode vir como uma surpresa, considerando que eles são capazes de fazer cálculos complexos em poucos segundos, de forma que nenhum humano conseguiria. Mas é verdade! Computadores são extremamente estúpidos e precisam de instruções exatas para tudo o que fazem. O que é óbvio para você, humano, certamente não é óbvio para uma máquina. E se você quer que a máquina faça algo pra você, bem, você precisa, de certa forma, “falar com ela”.

O que é Programa de Computador

É um conjunto de instruções que descrevem uma tarefa a ser realizada por um computador.

O que é Linguagem de Programação

Você já deve ter ouvido falar que computadores entendem apenas binário, ou seja, a linguagem de 0 e 1. Todas as instruções que são dadas para eles são traduzidas em sinais elétricos que significam, basicamente, ligado e desligado. Pense em uma pequena lâmpada. Quando ela está ligada, indica 0. Quando desligada, indica 1. Isso é binário. E há uma infinita quantidade de combinações que você pode fazer com isso.

real_programmer_binary

Pense em você e sua máquina. Você fala português, mas a sua máquina fala apenas binário. Entre você e a máquina está um intérprete, o compilador, mas ele só sabe binário e uma outra lingua – Java, por exemplo. Aprender a “falar” Java é muito mais fácil que aprender a “falar” binário. Isso porque Java possui muitas palavras em comum com o inglês,e você pode escrever instruções que você entende, como “imprima” ou “leia”, ao invés de 001010001010101010. Assim, quando você quer se comunicar com a sua máquina e criar uma série de instruções para ela seguir, você escreve em Java para o compilador e ele traduz as instruções para a máquina, em binário. Isso é uma linguagem de programação.

Tenho que saber inglês?

1435472631_rwerwerwerw

Saber um inglês perfeito não é necessário. Mas é bom saber algo e com o tempo você conhecerá algumas palavras por causa da programação. if, for e while são palavras do inglês que você nunca mais esquecerá quando estiver programando. Outras palavras virão dependendo do que estiver usando. Mas para tornar-se um bom programador, é necessário, pelo menos saber ler.

Vamos criar um Programa

tumblr_m7dnbqx0yp1r7elzl

Quais recursos teremos no blog

  • Inclusão, alteração e exclusão de postagem
  • Cada postagem poderá ter inúmeros comentários
  • Inclusão, alteração e exclusão de comentários

O que é CRUD

mongodb-crud-operations1

CRUD é o acrônimo da expressão do idioma Inglês, Create (Criação), Retrieve (Consulta), Update (Atualização) e Delete (Destruição).

Começando do começo

Vamos criar nossa aplicação em Ruby on Rails:

rails new blog

Isto criará nossa estrutura de pastas padrão do Rails. A primeira coisa a reparar é o ambiente: agora temos esta estrutura principal:

emmanuelle@richard:~/tutorial$ rails new blog
create
create README.rdoc
create Rakefile
create config.ru
create .gitignore
create Gemfile
create app
create app/assets/javascripts/application.js
create app/assets/stylesheets/application.css
create app/controllers/application_controller.rb
create app/helpers/application_helper.rb
create app/views/layouts/application.html.erb
create app/assets/images/.keep
create app/mailers/.keep
create app/models/.keep
create app/controllers/concerns/.keep
create app/models/concerns/.keep
create bin
create bin/bundle
create bin/rails
create bin/rake
create bin/setup
create config
create config/routes.rb
create config/application.rb
create config/environment.rb
create config/secrets.yml
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
create config/initializers
create config/initializers/assets.rb
create config/initializers/backtrace_silencers.rb
create config/initializers/cookies_serializer.rb
create config/initializers/filter_parameter_logging.rb
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/initializers/session_store.rb
create config/initializers/wrap_parameters.rb
create config/locales
create config/locales/en.yml
create config/boot.rb
create config/database.yml
create db
create db/seeds.rb
create lib
create lib/tasks
create lib/tasks/.keep
create lib/assets
create lib/assets/.keep
create log
create log/.keep
create public
create public/404.html
create public/422.html
create public/500.html
create public/favicon.ico
create public/robots.txt
create test/fixtures
create test/fixtures/.keep
create test/controllers
create test/controllers/.keep
create test/mailers
create test/mailers/.keep
create test/models
create test/models/.keep
create test/helpers
create test/helpers/.keep
create test/integration
create test/integration/.keep
create test/test_helper.rb
create tmp/cache
create tmp/cache/assets
create vendor/assets/javascripts
create vendor/assets/javascripts/.keep
create vendor/assets/stylesheets
create vendor/assets/stylesheets/.keep
run bundle install

O que são Bibliotecas

giphy

Bibliotecas são conjuntos de funções pré-escritas por outros programadores que já resolvem determinados problemas sem que você precise “reinventar a roda”, semelhantes a plugins.

No Rails, Bibliotecas são chamadas de Gemas (Gem).  Talvez seja necessário instalar algumas.

emmanuelle@richard:~/tutorial$ bundle install
Your user account isn't allowed to install to the system Rubygems.
You can cancel this installation and run:

bundle install --path vendor/bundle

to install the gems into ./vendor/bundle/, or you can enter your password
and install the bundled gems to Rubygems using sudo.

Password:

Digite a senha

Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies....
Using rake 11.2.2
Using i18n 0.7.0
Using json 1.8.3
Using minitest 5.9.0
Using thread_safe 0.3.5
Using builder 3.2.2
Using erubis 2.7.0
Using mini_portile2 2.1.0
Using pkg-config 1.1.7
Using rack 1.6.4
Using mime-types-data 3.2016.0521
Using arel 6.0.3
Using debug_inspector 0.0.2
Using bundler 1.11.2
Using byebug 9.0.5
Using coffee-script-source 1.10.0
Using execjs 2.7.0
Using thor 0.19.1
Using concurrent-ruby 1.0.2
Using multi_json 1.12.1
Using sass 3.4.22
Using tilt 2.0.5
Installing spring 1.7.2
Installing sqlite3 1.3.11 with native extensions
Installing turbolinks-source 5.0.0
Using rdoc 4.2.2
Using tzinfo 1.2.2
Using nokogiri 1.6.8
Using rack-test 0.6.3
Using mime-types 3.1
Using binding_of_caller 0.7.2
Using coffee-script 2.4.1
Using uglifier 3.0.0
Installing sprockets 3.6.3
Installing turbolinks 5.0.0
Using sdoc 0.4.1
Using activesupport 4.2.6
Using loofah 2.0.3
Using mail 2.6.4
Using rails-deprecated_sanitizer 1.0.3
Using globalid 0.3.6
Using activemodel 4.2.6
Using jbuilder 2.5.0
Using rails-html-sanitizer 1.0.3
Using rails-dom-testing 1.0.7
Using activejob 4.2.6
Using activerecord 4.2.6
Using actionview 4.2.6
Using actionpack 4.2.6
Using actionmailer 4.2.6
Using railties 4.2.6
Installing sprockets-rails 3.1.1
Using coffee-rails 4.1.1
Using jquery-rails 4.1.1
Using rails 4.2.6
Installing sass-rails 5.0.5
Using web-console 2.3.0
Bundle complete! 12 Gemfile dependencies, 57 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
         run  bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted

Entre no diretório da aplicação

emmanuelle@richard:~/tutorial$ cd blog

e inicialize o servidor web

emmanuelle@richard:~/tutorial/blog$ rails server
=> Booting WEBrick
=> Rails 4.2.6 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2016-07-05 12:09:35] INFO  WEBrick 1.3.1
[2016-07-05 12:09:35] INFO  ruby 2.2.3 (2015-08-18) [x86_64-linux]
[2016-07-05 12:09:35] INFO  WEBrick::HTTPServer#start: pid=4936 port=3000

Acesse no navegador o endereço: http://localhost:3000

Se tudo estiver correto, aparecerá:

giphy (2)

O que é um Servidor Web

webserver-basic-sm

Programa de computador responsável por aceitar pedidos HTTP de clientes, geralmente os navegadores, e servi-los com respostas HTTP, incluindo opcionalmente dados, que geralmente são páginas web, tais como documentos HTML com objetos embutidos (imagens, etc.)

O que é porta

image-04-700x522

Qualquer máquina do servidor disponibiliza seus serviços para a Internet usando portas numeradas, uma para cada serviço que está disponível no servidor. Por exemplo, se uma máquina servidor está executando um servidor Web e um servidor de e-mail, o servidor Web normalmente ficaria disponível na porta 80, e o servidor de e-mail estaria disponível na porta 587.

Vamos criar nosso primeiro recurso

2rmsk5e

emmanuelle@richard:~/tutorial/blog$ rails g scaffold Post title:string body:text
Running via Spring preloader in process 3625
      invoke  active_record
      create    db/migrate/20160706133325_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml
      invoke  resource_route
       route    resources :posts
      invoke  scaffold_controller
      create    app/controllers/posts_controller.rb
      invoke    erb
      create      app/views/posts
      create      app/views/posts/index.html.erb
      create      app/views/posts/edit.html.erb
      create      app/views/posts/show.html.erb
      create      app/views/posts/new.html.erb
      create      app/views/posts/_form.html.erb
      invoke    test_unit
      create      test/controllers/posts_controller_test.rb
      invoke    helper
      create      app/helpers/posts_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/posts/index.json.jbuilder
      create      app/views/posts/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/posts.coffee
      invoke    scss
      create      app/assets/stylesheets/posts.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

O que é Banco de Dados

tirinha112

Um banco de dados é uma aplicação que lhe permite armazenar e obter de volta dados com eficiência.

Banco de Dados Relacional

banco-de-dados-relacionais-1

Em um banco de dados relacional, todos os dados são guardados em tabelas. Estas têm uma estrutura que se repete a cada linha, como você pode observar em uma planilha. São os relacionamentos entre as tabelas que as tornam “relacionais”.

Tabelas

Uma tabela é uma simples estrutura de linhas e colunas. Em uma tabela, cada linha contém um mesmo conjunto de colunas. Em um banco de dados podem existir uma ou centenas de tabelas, sendo que o limite pode ser imposto tanto pela ferramenta de software utilizada, quanto pelos recursos de hardware disponíveis no equipamento.

Registros

Cada linha formada por uma lista ordenada de colunas representa um registro, ou tupla. Os registros não precisam conter informações em todas as colunas, podendo assumir valores nulos quando assim se fizer necessário.

Atributos

As colunas de uma tabela são também chamadas de atributos. Ex.: O campo Nome, ou endereço de uma tabela de um BD relacional.

Chave

As tabelas relacionam-se umas as outras através de chaves. Uma chave é um conjunto de um ou mais atributos que determinam a unicidade de cada registro.

Por exemplo, se um banco de dados tem como chaves Código do Produto e ID Sistema, sempre que acontecer uma inserção de dados o sistema de gerenciamento de banco de dados irá fazer uma consulta para identificar se o registro já não se encontra gravado na tabela. Neste caso, um novo registro não será criado, resultando esta operação apenas da alteração do registro existente.

O que é Tipo de Dados

Uma calculadora simples, de bolso, capaz de fazer apenas as 4 operações básicas, não pode aceitar nada além de números e de comandos para realizar cálculos.  Essa calculadora aceita apenas e exclusivamente dados do tipo número.

um tipo de dados é uma identificação que determina os valores possíveis para esse dado, as operações que podem ser feitas, seu significado, e a forma como o valor desse dado pode ser armazenado.

As linguagens de programação normalmente estabelecem regras precisas para definir que tipos de dados elas irão manipular.

pasted image 0

Criando as tabelas da aplicação

Vamos agora fazer a migração

emmanuelle@richard:~/tutorial/blog$ rake db:migrate
== 20160706133325 CreatePosts: migrating ======================================
-- create_table(:posts)
   -> 0.0009s
== 20160706133325 CreatePosts: migrated (0.0009s) =============================

Acessando agora nossa aplicação nos posts

Podemos agora criar um novo post para o blog

novopost

Podemos também editar o post

Screenshot from 2016-07-06 10:57:19 posteditado editadocomsucessoScreenshot from 2016-07-06 10:57:19

Rotas

39

Uma rota é um caminho para uma ação de um controlador qualquer e no Rails o arquivo config/routes.rb contém todas as rotas que serão usadas pela aplicação.

# config/routes.rb
Rails.application.routes.draw do
   resources :posts
end

REST

REST é um modelo arquitetural para sistemas distribuídos. A ideia básica é que existe um conjunto fixo de operações permitidas (verbs) e as diversas aplicações se comunicam aplicando este conjunto fixo de operações em recursos existentes, podendo ainda pedir diversas representações destes recursos.

A sigla REST vem de Representational State Transfer.

As operações disponíveis para cada um dos recursos são:

  • GET: retorna uma representação do recurso
  • POST: criação de um novo recurso
  • PUT: altera o recurso
  • DELETE: remove o recurso

Os quatro verbos do protocolo HTTP são comumente associados às operações de CRUD em sistemas Restful.

 A principal forma de suporte no Rails a estes padrões é através de rotas que seguem as convenções da arquitetura REST. Ao mapear um recurso no routes.rb, o Rails cria automaticamente as rotas adequadas no controlador para tratar as operações disponíveis no recurso (GET, POST, PUT e DELETE).
emmanuelle@richard:~/tutorial/blog$ rake routes
      Prefix Verb   URI Pattern                  Controller#Action
       posts GET    /posts(.:format)             posts#index
             POST   /posts(.:format)             posts#create
    new_post GET    /posts/new(.:format)         posts#new
   edit_post GET    /posts/:id/edit(.:format)    posts#edit
        post GET    /posts/:id(.:format)         posts#show
             PATCH  /posts/:id(.:format)         posts#update
             PUT    /posts/:id(.:format)         posts#update
             DELETE /posts/:id(.:format)         posts#destroy
        root GET    /                            posts#index

Vamos dizer ao Rails que a página raiz da aplicação é a localhost:3000/posts, fazendo assim no arquivo config/routes.rb:

Rails.application.routes.draw do
...
root 'posts#index'
...
end

Agora quando acessarmos “http://localhost:3000” aparecerá:

Adicionando Comentários

nazare-rindo-o

Criaremos agora um recurso de comentário para os posts. Isto irá completar as funcionalidades do Blog.

Dizendo  o óbvio:  Um post terá vários comentários, mas um comentário será ligado a apenas um post.

Relacionamentos

RELACIONAMENTO UM PARA MUITOS (U:M)

Um relacionamento 1:m ocorre com frequência. No exemplo abaixo, temos a seguinte representação: Cada curso cadastrado possui vários alunos ligados a ele, pois cada aluno, ao ser cadastrado, deverá ser ligado a um curso obrigatóriamente. O campo codigocurso foi escolhido como chave primária na tabela CURSO, ou seja, ela não poderá se repetir. Já na tabela ALUNO, a chave primária é matricula e o codigocurso é chave estrangeira. A representação ficaria assim:

aula_7_relacionamento.bmp

Como lemos este relacionamento:

  • UM curso tem MUITOS alunos
  • UM aluno tem UM curso

RELACIONAMENTOS MUITOS PARA MUITOS (M:M)

Uma ocorrencia de uma tabela em A está associada a qualquer número de ocorrencias na tabela B, e cada ocorrencia da tabela em B está associada a qualquer número de ocorrencias na tabela A.

Considere o caso em que itens são vendidos. Podemos identificar imediatamente duas entidades: VENDA e ITEM. Uma venda pode consistir em muitos itens de mercadorias e um item de mercadoria pode aparecer em muitas vendas. Não estamos dizendo que um mesmo item possa ser vendido muitas vezes, mas que o tipo específico de item (por exemplo, um livro ) pode ser vendido muitas vezes; temos, portanto, um relacionamento de muitos-para-muitos (m:m) entre VENDA e ITEM. Em um relacionamento m:m, criamos uma terceira entidade, chamada entidade associativa que é usada para associar as entidades por meio de dois relacionamentos 1:m. De maneira geral, é razoavelmente fácil nomear essa terceira entidade. Nesse exemplo, essa terceira entidade, geralmente conhecida como entidade associativa, é chamada de VENDA_MERCADORIA.

Observe abaixo e atente para a representação do relacionamento. Cada uma das linhas que aparece no formulário do pedido de vendas é, em geral, conhecida no varejo como um item de linha, onde o código da mercadoria é ligado a uma venda.

aula_7_relacionamento2.bmp

A representação desse relacionamento m:m é mostrada na figura acima. Dizemos muitos para muitos porque há dois relacionamentos: CODIGO DA MERCADORIA está relacionado com muitas VENDAS e VENDA está relacionada com muitos CÓDIGOS DE MERCADORIA.

No caso do nosso exemplo, a entidade associativa é a VENDA_MERCADORIA. Podemos fazer a leitura do relacionamento acima da seguinte forma:

  • UMA venda tem VÁRIOS itens de mercadoria
  • UMA mercadoria tem VÁRIAS vendas

RELACIONAMENTO UM PARA UM (1:1)

São relacionamentos em que uma ocorrencia de uma entidade em A está associada no máximo a uma ocorrencia em uma entidade B e uma ocorrencia na entidade B está associada no máximo a uma ocorrencia na entidade A.

Neste relacionamento, escolhemos qual tabela irá receber a chave estrangeira, e para cada valor do campo na tabela A, há no máximo um valor na tabela B.

No exemplo mostrado na Figura abaixo podemos entender melhor este tipo de relacionamento, onde estaremos definindo que um Gerente (e somente um) gerencia um (e somente um) Departamento. Ou seja, o mesmo Gerente não pode gerenciar mais de um Departamento e um Departamento não poderá ser gerenciado por mais de um Gerente.

aula_7_relacionamento3.bmp

Nesse caso lemos:

  • UM gerente tem APENAS UM departamento
  • UM departamento tem APENAS UM gerente

Criando o recurso de Comentários

emmanuelle@richard:~/tutorial/blog$ rails g scaffold Comment post:references body:text
Running via Spring preloader in process 4399
      invoke  active_record
      create    db/migrate/20160706140224_create_comments.rb
      create    app/models/comment.rb
      invoke    test_unit
      create      test/models/comment_test.rb
      create      test/fixtures/comments.yml
      invoke  resource_route
       route    resources :comments
      invoke  scaffold_controller
      create    app/controllers/comments_controller.rb
      invoke    erb
      create      app/views/comments
      create      app/views/comments/index.html.erb
      create      app/views/comments/edit.html.erb
      create      app/views/comments/show.html.erb
      create      app/views/comments/new.html.erb
      create      app/views/comments/_form.html.erb
      invoke    test_unit
      create      test/controllers/comments_controller_test.rb
      invoke    helper
      create      app/helpers/comments_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/comments/index.json.jbuilder
      create      app/views/comments/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/comments.coffee
      invoke    scss
      create      app/assets/stylesheets/comments.scss
      invoke  scss
   identical    app/assets/stylesheets/scaffolds.scss

Devemos sempre fazer a migração

emmanuelle@vitory:~/tutorial/blog$ rake db:migrate
== 20160706140224 CreateComments: migrating ===================================
-- create_table(:comments)
   -> 0.0017s
== 20160706140224 CreateComments: migrated (0.0018s) ==========================

Configurando relacionamentos

Vamos configurar os relacionamentos entre os models:

adicioneicommentsnopost
Adicionei > has_many   :comments < no model dos posts
Screenshot from 2016-07-06 11:16:01
No meu model dos comments já tinha > belongs_to   :post <

Replicando os relacionamentos nas rotas

Gostaríamos de ter URLs como estas:

http://localhost:3000/posts/1/comments
http://localhost:3000/posts/1/comments/new
http://localhost:3000/posts/1/comments/3

No config/routes.rb temos:

# config/routes.rb
Rails.application.routes.draw do
 resources :comments
 resources :posts 

 root 'posts#index'
end

Que faz com que os comments ainda não fiquem relacionados com os posts:

emmanuelle@richard:~/tutorial/blog$ rake routes
      Prefix Verb   URI Pattern                  Controller#Action
    comments GET    /comments(.:format)          comments#index
             POST   /comments(.:format)          comments#create
 new_comment GET    /comments/new(.:format)      comments#new
edit_comment GET    /comments/:id/edit(.:format) comments#edit
     comment GET    /comments/:id(.:format)      comments#show
             PATCH  /comments/:id(.:format)      comments#update
             PUT    /comments/:id(.:format)      comments#update
             DELETE /comments/:id(.:format)      comments#destroy
       posts GET    /posts(.:format)             posts#index
             POST   /posts(.:format)             posts#create
    new_post GET    /posts/new(.:format)         posts#new
   edit_post GET    /posts/:id/edit(.:format)    posts#edit
        post GET    /posts/:id(.:format)         posts#show
             PATCH  /posts/:id(.:format)         posts#update
             PUT    /posts/:id(.:format)         posts#update
             DELETE /posts/:id(.:format)         posts#destroy
        root GET    /                            posts#index

Como no modelo, podemos criar o que é chamado de Rotas aninhadas:

# config/routes.rb
Rails.application.routes.draw do

  resources :posts do
    resources :comments
  end

  root 'posts#index'
end

Agora as rotas dos comments estão diretamente relacionadas com as dos post:

emmanuelle@richard:~/tutorial/blog$ rake routes
           Prefix Verb   URI Pattern                                 Controller#Action
    post_comments GET    /posts/:post_id/comments(.:format)          comments#index
                  POST   /posts/:post_id/comments(.:format)          comments#create
 new_post_comment GET    /posts/:post_id/comments/new(.:format)      comments#new
edit_post_comment GET    /posts/:post_id/comments/:id/edit(.:format) comments#edit
     post_comment GET    /posts/:post_id/comments/:id(.:format)      comments#show
                  PATCH  /posts/:post_id/comments/:id(.:format)      comments#update
                  PUT    /posts/:post_id/comments/:id(.:format)      comments#update
                  DELETE /posts/:post_id/comments/:id(.:format)      comments#destroy
            posts GET    /posts(.:format)                            posts#index
                  POST   /posts(.:format)                            posts#create
         new_post GET    /posts/new(.:format)                        posts#new
        edit_post GET    /posts/:id/edit(.:format)                   posts#edit
             post GET    /posts/:id(.:format)                        posts#show
                  PATCH  /posts/:id(.:format)                        posts#update
                  PUT    /posts/:id(.:format)                        posts#update
                  DELETE /posts/:id(.:format)                        posts#destroy
             root GET    /                                           posts#index

Simples assim! Agora podemos fazer URLs aninhadas como mostrado acima. A primeira coisa a entender é que quando escreve-se esta URL:

http://localhost:3000/posts/1/comments

Rails entenderá como:

* Carregar CommentsController
* Configurar o params[:post_id] = 1
* Neste caso, chamar o 'index' action

Nós temos que preparar o CommentsController para este aninhamento. Então, o que mudaremos:

class CommentsController < ApplicationController
  before_action :load_post
  ...
  def load_post
    @post = Post.find(params[:post_id])
  end
end

Agora temos que fazer estas alterações no controller (controllers/comments_controller.rb):

Substitua Por
Comment.find @post.comments.find
Comment.new @post.comments.build
redirect_to(@comment) redirect_to([@post, @comment])
redirect_to(comments_url) redirect_to(post_comments_url(@post))

Ficará assim:

class CommentsController < ApplicationController
  before_action :set_comment, only: [:show, :edit, :update, :destroy]
  before_action :load_post

  # GET /comments
  # GET /comments.json
  def index
    @comments = @post.comments
  end

  # GET /comments/1
  # GET /comments/1.json
  def show
  end

  # GET /comments/new
  def new
    # @comment = Comment.new
    @comment =@post.comments.build
  end

  # GET /comments/1/edit
  def edit
  end

  # POST /comments
  # POST /comments.json
  def create
    @comment = Comment.new(comment_params)
    @comment.post_id = params[:post_id]
    respond_to do |format|
      if @comment.save
        format.html { redirect_to [@post, @comment], notice: 'Comment was successfully created.' }
        format.json { render :show, status: :created, location: @comment }
      else
        format.html { render :new }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /comments/1
  # PATCH/PUT /comments/1.json
  def update
    respond_to do |format|
      if @comment.update(comment_params)
        format.html { redirect_to [@post, @comment], notice: 'Comment was successfully updated.' }
        format.json { render :show, status: :ok, location: @comment }
      else
        format.html { render :edit }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /comments/1
  # DELETE /comments/1.json
  def destroy
    @comment.destroy
    respond_to do |format|
      format.html { redirect_to post_comments_url(@post), notice: 'Comment was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def load_post
    @post = Post.find(params[:post_id])
  end


  private
    # Use callbacks to share common setup or constraints between actions.
    def set_comment
      @comment = Comment.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def comment_params
      params.require(:comment).permit(:post_id, :body)
    end
end

Isto deixará o controller Comments preparado.

Para criar um link para exibir os comentários na visualização do post é só adicionar em posts/show.html.erb:

<%= link_to 'Comments', post_comments_path(@post) %>

Screenshot from 2016-07-07 11:53:10

No browser ficará assim:

Screenshot from 2016-07-07 11:53:59

Vamos corrigir o arquivo comments/index .html.erb para exibir o link correto para manipular os comentários:

Substitua Por
<%= link_to ‘Show’, comment %> <%= link_to ‘Show’, post_comment_path(@post, comment) %>
<%= link_to ‘Edit’, edit_comment_path(comment) %> <%= link_to ‘Edit’, edit_post_comment_path(@post, comment) %>
<%= link_to ‘Destroy’, comment, method: :delete, data: { confirm: ‘Are you sure?’ } %> <%= link_to ‘Destroy’, [@post, comment], method: :delete, data: { confirm: ‘Are you sure?’ } %>
<%= link_to ‘New Comment’, new_comment_path %> <%= link_to ‘New Comment’, new_post_comment_path(@post) %>

Ficará assim:

<p id="notice"><%= notice %></p>

<h1>Listing Comments</h1>

<table>
 <thead>
 <tr>
 <th>Post</th>
 <th>Body</th>
 <th colspan="3"></th>
 </tr>
 </thead>

 <tbody>
 <% @comments.each do |comment| %>
 <tr>
 <td><%= link_to comment.post.title, post_path(@post) %></td>
 <td><%= comment.body %></td>
 <td><%= link_to 'Show', post_comment_path(@post, comment) %></td>
 <td><%= link_to 'Edit', edit_post_comment_path(@post, comment) %></td>
 <td><%= link_to 'Destroy', [@post, comment], method: :delete, data: { confirm: 'Are you sure?' } %></td>
 </tr>
 <% end %>
 </tbody>
</table>

<br>

<%= link_to 'New Comment', new_post_comment_path(@post) %>

Clicando no link “Comments” será exibido:

Antes de adicionar um comentário vamos fazer uns ajustes na view comments/new.html.erb
Substitua Por
<%= link_to ‘Back’, comments_path %> <%= link_to ‘Back’, post_comments_path(@post) %>

Ficará assim:

Screenshot from 2016-07-08 09:38:38

e no partial comments/_form.html.erb

Substitua Por
<%= form_for(@comment) do |f| %> <%= form_for([@post, @comment]) do |f| %>

Remova

<div>
 <%= f.label :post_id %>
 <%= f.text_field :post_id %>
</div>
Ficará assim:

Screenshot from 2016-07-07 12:05:27

Clicando no link “New Comment”:

Screenshot from 2016-07-07 12:06:35

Quando clicarmos no botão “Create Comment”:

Antes de editar um comentário vamos fazer uns ajustes na view comments/edit.html.erb:

Screenshot from 2016-07-08 09:39:34

Clicando no botão “Edit”:

Clicando no botão “Update Comment”:

E no arquivo comments/show.html.erb para exibir o post:

<p id="notice"><%= notice %></p>

<p>
 <strong>Post:</strong>
 <%= @comment.post.title %>
</p>

<p>
 <strong>Body:</strong>
 <%= @comment.body %>
</p>

<%#= link_to 'Edit', edit_comment_path(@comment) %> |
<%#= link_to 'Back', comments_path %>

<%= link_to 'Edit', [:edit, @post, @comment] %> |
<%= link_to 'Back', post_comments_path(@post) %>

 

Agora vamos verificar se está tudo correto:

Screenshot from 2016-07-08 09:47:55

Clicando no link “Comments”, teremos:

Screenshot from 2016-07-08 09:48:55

 

 

 

angie1gif

Fontes:

http://canaltech.com.br/o-que-e/o-que-e/o-que-e-uma-linguagem-de-programacao/

https://sites.google.com/site/uniplibancodedados1/aulas/aula-7—tipos-de-relacionamento

https://pt.wikipedia.org/wiki/Banco_de_dados_relacional

https://www.caelum.com.br/apostila-ruby-on-rails/rotas/#8-4-rest-resources

Autor: Emmanuelle Richard

Desenvolvi meu primeiro aplicativo aos 12 anos e desde então minha vida mudou. Já palestrei em diversos eventos como a Campus Party, Flisol, PhP Experience e outros, mostrando a todos que programar é divertido além de ser uma atividade fascinante, e, graças à programação, tenho conhecido muitas pessoas inspiradoras fascinando-me cada vez mais com este novo mundo que surgiu à minha frente. Contato: Email: emmanuellerichard@onbit.com.br Telefone: 84 9 86229868/ 84 9 88296900