Closed vanderleipinto closed 6 months ago
O projeto foi criado usando o comando
rails new TT4 --api -d mysql
O comando rails new TT4 --api -d mysql
é utilizado para criar um novo projeto Rails chamado "TT4" configurado como uma API e utilizando o banco de dados MySQL. Vamos analisar cada opção fornecida:
--api
: Esta opção indica que o projeto Rails será configurado como uma API, o que significa que ele será simplificado e otimizado para servir apenas APIs JSON, excluindo funcionalidades que não são necessárias em uma API tradicional, como as views geradas pelo Rails para aplicativos da web tradicionais.
-d mysql
: Esta opção especifica que o banco de dados padrão para o projeto será o MySQL. O Rails utiliza SQLite por padrão em projetos novos, mas ao fornecer essa opção, você está indicando que deseja usar o MySQL como banco de dados para este projeto.
Portanto, o comando rails new TT4 --api -d mysql
, cria um novo projeto Rails configurado como uma API e utilizando o banco de dados MySQL como backend de armazenamento de dados. Isso é útil quando se cria uma aplicação que servirá principalmente como uma API JSON e não precisa de toda a complexidade de uma aplicação Rails tradicional com views HTML.
Adicionamos a gem 'csv' no arquivo Gemfile
O model foi criado usando o comando
rails g scaffold movies show_id type director cast:text country date_added release_year rating duration listed_in:text description:text
Os atributos foram retirados do header do arquivo csv.
O comando rails g scaffold
é uma forma de gerar rapidamente uma estrutura básica para um recurso no Rails, incluindo um modelo, uma migração de banco de dados, um controller e views associadas. Vamos analisar os componentes do comando fornecido:
rails g
: Este é o comando abreviado para "rails generate", que é usado para gerar código automaticamente no Rails.
scaffold
: Esta é uma opção do gerador que cria uma estrutura completa de CRUD (Create, Read, Update, Delete) para o recurso especificado. Isso inclui um modelo, uma migração de banco de dados, um controller com métodos para manipular as operações CRUD e views para exibir os dados.
movies
: Este é o nome do recurso que está sendo criado. No contexto do comando scaffold
, isso será o nome do modelo, controller e views associadas ao recurso.
show_id type director cast:text country date_added release_year rating duration listed_in:text description:text
: Estes são os atributos do modelo Movie
que está sendo criado. Cada atributo especificado será adicionado ao modelo Movie
com o tipo de dados apropriado. Por exemplo, show_id
e type
serão strings, date_added
será uma data, cast
, listed_in
e description
serão textos, e assim por diante.
Portanto, ao executar o comando rails g scaffold movies show_id type director cast:text country date_added release_year rating duration listed_in:text description:text
,que está sendo criado um scaffold completo para o recurso "movies", incluindo um modelo Movie
com os atributos especificados, uma migração de banco de dados para criar a tabela correspondente no banco de dados, um controller MoviesController
com métodos para manipular operações CRUD, como o projeto foi criado focado no api, as views não serão criadas.
O arquivo app/models/movie.rb ficou da seguinte maneira:
class Movie < ApplicationRecord
validates :title, uniqueness: true
end
validates :title, uniqueness: true
=> Aqui faz-se uma validação de modo que o banco de dados não aceita dois movies com o mesmo title.
Vamos alterar o arquivo config/database.yml para que o sistema possa acessar o banco de dados. Vamos adicionar a senha do banco de dados na nossa máquina. No nosso caso 1234
``yml default: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: 1234 socket: /var/run/mysqld/mysqld.sock
Agora podemos gerar o banco de dados com o comando:
`rails db:create`
Uma vez criado o bando de dados vamos adicionar a tabela do movies com o comando:
`rails db:migrate`
Esse comando usa como parâmetro o arquivo gerado anteriormente com o comando rails g scaffold. Esse comando criou um arquivo em db/migrate/XXX_create_movies.rb.
```ruby
class CreateMovies < ActiveRecord::Migration[7.1]
def change
create_table :movies do |t|
t.string :show_id
t.string :genre
t.string :title
t.string :director
t.text :cast
t.string :country
t.date :date_added
t.string :release_year
t.string :rating
t.string :duration
t.text :listed_in
t.text :description
t.timestamps
end
end
end
OBS: Substituímos o header type
por genre
já que type é uma palavra privada e não é aceita como nome de coluna no banco de dados. Faremos as mudanças necessárias no controller.
Agora já temos o banco de dados com a tabela necessária para a inserção de dados.
Adicionada a seguinte rota:
resources :movies, only: [:index, :create]
get '/movies/read_csv', to: 'movies#read_csv'
O arquivo routes.rb
é uma parte fundamental de um aplicativo Rails. Ele é responsável por definir as rotas da aplicação, ou seja, as URLs que o aplicativo responderá e quais controladores e ações serão acionados em resposta a essas URLs.
O comando resources
é uma forma conveniente de definir rotas RESTful em um aplicativo Rails. Ele gera automaticamente várias rotas padrão que são comumente usadas em uma arquitetura RESTful, incluindo rotas para criar, ler, atualizar e excluir recursos.
Por exemplo, ao adicionar resources :movies
ao arquivo routes.rb
, estão sendo geradas automaticamente as seguintes rotas:
GET /movies
: Mostra uma lista de todos os filmes.GET /movies/new
: Exibe um formulário para criar um novo filme.POST /movies
: Cria um novo filme.GET /movies/:id
: Mostra os detalhes de um filme específico.GET /movies/:id/edit
: Exibe um formulário para editar um filme.PATCH /movies/:id
ou PUT /movies/:id
: Atualiza um filme específico.DELETE /movies/:id
: Exclui um filme específico.Essas rotas podem ser personalizadas ou ampliadas conforme necessário, mas o comando resources
fornece uma maneira rápida e fácil de definir as rotas básicas para um recurso em um aplicativo Rails. O arquivo routes.rb
é onde todas essas rotas são definidas e configuradas para o aplicativo.
Como foi o caso da adição da rota get '/movies/read_csv', to: 'movies#read_csv'
Essa é uma rota para a action que lê o arquivo csv, altera alguns dados e salva no banco de dados.
O arquivo app/controllers/movies_controller.rb foi criado automaticamente com as actions necessárias para uma API. Agora faremos algumas alterações para o funcionamento do sistema de acordo com nossas necessidades.
Responsável pela
- Leitura do arquivo csv
- Conversão o valor do campo date_added(string) para Date
- Modificão da key type para genre para se adequar ao banco de dados.
def read_csv
csv_data = []
CSV.foreach('app/data/TT_ 4 - netflix_titles.csv', headers: true) do |row|
csv_data << row.to_hash
end
#converte o valor do campo date_added(string) para Date modifica a key type para movie_type
csv_data.each do |item|
item['genre'] = item['type']
item.delete('type')
item['date_added'] = Date.strptime(item['date_added'],"%h %d, %y")
end
#insere todos os valores no Banco de Dados
csv_data.each do |movie_data|
Movie.create(movie_data)
end
render json: Movie.all
end
A sequir ele faz a leitura do arquivo csv. Transforma em hash e insere na array csv_data
csv_data = []
#Leitura do arquivo csv. Transforma em hash e insere na array csv_data
CSV.foreach('app/data/TT_ 4 - netflix_titles.csv', headers: true) do |row|
csv_data << row.to_hash
end
Obs: o CSV é da gem 'csv'.
Então faz-se a conversão do valor do campo date_added(string) para Date e modificação da key type para movie_type
#converte o valor do campo date_added(string) para Date modifica a key type para movie_type
csv_data.each do |item|
item['genre'] = item['type']
item.delete('type')
item['date_added'] = Date.strptime(item['date_added'],"%h %d, %y")
end
Agora é só percorrer a hash e inserir no banco de dados, seguindo o código abaixo.
#insere todos os valores no Banco de Dados
csv_data.each do |movie_data|
Movie.create(movie_data)
end
def index
@movies = Movie.select(:id, :title, :genre, :release_year, :country , :date_added, :description ).order(:release_year)
# Filtragem por ano
@movies = @movies.where("genre like ? and country like ? and release_year like ?" ,"%#{params[:genre]}%", "%#{params[:country]}%", "%#{params[:release_year]}%")
render json: @movies
end
A variável @movies vai consultar o banco de dados fazendo um select
somente para os dados que queremos:
@movies = Movie.select(:id, :title, :genre, :release_year, :country , :date_added, :description ).order(:release_year)
A sequir temos a filtragem dos dados de acordo com os parâmetros recebidos:
@movies = @movies.where("genre like ? and country like ? and release_year like ?" ,"%#{params[:genre]}%", "%#{params[:country]}%", "%#{params[:release_year]}%")
E então renderizamos o resultado em formato de json.
Desafio API
Criar um endpoint que faça a leitura de um arquivo .csv, popule o banco de dados com essas informações e com isso será necessário exibir todos os registros em json.
Requisitos:
Dicas: ● Testes são bem-vindos;; ● Tipo de banco de dados em aberto, pode escolher tanto relacional quanto não relacional; ● O filtro pode ser aplicado por 1 ou mais itens, mas devem atender aos requisitos; ● O arquivo .csv, entitulado netflix_titles.csv, poderá ser encontrado no anexo do email com o desafio;