"O êxito parece doce a quem não o alcança"
Vimos que quando usamos o gerador scaffold o Rails cria os arquivos necessários em todas as camadas. Controller, Model, Views e até mesmo arquivos de testes e a Migration. Para concluir nossos projeto precisamos criar apenasController + Views pois tanto o modelo quanto as migrations já estão prontos. Para isso vamos usar o mesmo gerador scaffold mas vamos passar os parâmetros: --migration=false para ele ignorar a criação da migration e o parâmetro -s que é a abreviação para --skip que faz com que o rails "pule" os arquivos já existentes.
Para concluir os modelos que já começamos vamos executar o gerador da seguinte maneira: rails generate scaffold cliente nome:string idade:integer --migration=false -s
Para conhecer todas as opções de parâmetros que um gerador pode receber tente executá-lo passando o parâmetro -h Ex. rails generate scaffold -h
Vamos gerar os outros controllers e views usando o scaffold:
Primeiro vamos gerar o scaffold para cliente, no terminal execute:
$ rails generate scaffold cliente nome idade:integer --migration=false -s
Agora vamos gerar o scaffold de qualificacao, execute:
$ rails generate scaffold qualificacao cliente_id:integer restaurante_id:integer nota:float valor_gasto:float --migration=false -s
Note que precisamos utilizar a opção "--migration=false" no comando scaffold, além de informar manualmente os atributos utilizados em nossas migrations. Isso foi necessário, pois já tínhamos um migration pronto, e queríamos que o Rails gerasse os formulários das views para nós, e para isso ele precisaria conhecer os atributos que queríamos utilizar.
O comando scaffold, quando executado, gera um css mais bonito para nossa aplicação. Se quiser utilizá-lo, edite nosso layout (app/views/layouts/application.html.erb) e adicione a seguinte linha logo abaixo da tag <title>:
<%= stylesheet_link_tag 'scaffold' %>
Editoras tradicionais pouco ligam para ebooks e novas tecnologias. Não conhecem programação para revisar os livros tecnicamente a fundo. Não têm anos de experiência em didáticas com cursos.
Conheça a Casa do Código, uma editora diferente, com curadoria da Caelume obsessão por livros de qualidade a preços justos.
Casa do Código, ebook com preço de ebook.
Você já deve ter reparado que nossa view de adição e edição de qualificações está um tanto quanto estranha: precisamos digitar os IDs do cliente e do restaurante manualmente.
Para corrigir isso, podemos utilizar o FormHelper select, inserindo o seguinte código nas nossas views de adição e edição de qualificações:
<%= select('qualificacao', 'cliente_id', Cliente.order(:nome) {|p| [ p.nome, p.id]}) %>
em substituição ao:
<%= f.number_field :cliente_id %>
Mas existe um outro FormHelper mais elegante, que produz o mesmo efeito, ocollection_select:
<%= collection_select(:qualificacao, :cliente_id, Cliente.order(:nome), :id, :nome, {:prompt => true}) %>
Como estamos dentro de um form_for, podemos usar do fato de que o formulário sabe qual o nosso ActiveRecord, e com isso fazer apenas:
<%= f.collection_select(:cliente_id, Cliente.order(:nome), :id, :nome, {:prompt => true}) %>
Vamos utilizar o FormHelper collection_select para exibirmos o nome dos clientes e restaurantes nas nossas views da qualificação:
<%= f.number_field :cliente_id %>
<%= f.collection_select(:cliente_id, Cliente.order(:nome), :id, :nome, {:prompt => true}) %>
<%= f.number_field :restaurante_id %>
<%= f.collection_select(:restaurante_id, Restaurante.order(:nome), :id, :nome, {:prompt => true}) %>
A forma como implementamos o seletor de restaurante e cliente não é a mais adequada pois ela fere o modelo arquitetural que o rails se baseia, o MVC. Isso ocorre, pois estamos invocando Cliente.order(:nome) dentro da view, ou seja, a view está se comunicando com o modelo.
Vamos arrumar isso, criando as variáveis de instância @restaurantes e@clientes nas actions new e edit do QualificacoesController:
def new @clientes = Cliente.order :nome @restaurantes = Restaurante.order :nome # resto do código end
def edit @clientes = Cliente.order :nome @restaurantes = Restaurante.order :nome # resto do código end
Agora podemos usar as variáveis de instância no nosso partial form.
f.collection_select(:restaurante_id, @restaurantes, :id, :nome, {:prompt => true})
f.collection_select(:restaurante_id, @clientes, :id, :nome, {:prompt => true})
Observe que temos código duplicado no nosso QualificacoesController, vamos refatorar extraindo a criação das variáveis de instância para um método privado,
class QualificacoesController < ApplicationController # todas as actions private def preparar_form @clientes = Cliente.order :nome @restaurantes = Restaurante.order :nome end end
@clientes = Cliente.order :nome @restaurantes = Restaurante.order :nome
preparar_form
As actions new e edit estão funcionando perfeitamente. Vamos analisar a actioncreate. Observe que caso dê erro de validação, ela também irá renderizar a viewnew.html.erb. Logo, é necessário criarmos as variáveis de instância@restaurantes e @clientes também na action create.
def create @qualificacao = Qualificacao.new(params[:qualificacao]) respond_to do |format| if @qualificacao.save format.html { redirect_to @qualificacao, notice: 'Qualificacao was successfully created.' } format.json { render json: @qualificacao, status: :created, location: @qualificacao } else preparar_form format.html { render action: "new" } format.json { render json: @qualificacao.errors, status: :unprocessable_entity } end end end
O mesmo problema da action create ocorre na action update, portanto vamos alterá-la.
def update @qualificacao = Qualificacao.find(params[:id]) respond_to do |format| if @qualificacao.update_attributes(params[:qualificacao]) format.html { redirect_to @qualificacao, notice: 'Qualificacao was successfully updated.' } format.json { head :no_content } else preparar_form format.html { render action: "edit" } format.json { render json: @qualificacao.errors, status: :unprocessable_entity } end end end
Inicie o servidor (rails server) e tente criar uma qualificação inválida para testar nossa correção.
A Alura oferece dezenas de cursos online em sua plataforma exclusiva de ensino que favorece o aprendizado com aqualidade reconhecida da Caelum. Você pode escolher um curso nas áreas de Java, Ruby, Web, Mobile, .NET e outros, ou fazer a assinatura semestral que dá acesso a todos os cursos.
Conheça os cursos online da Caelum.
Agora vamos exibir o nome dos restaurantes e clientes nas views index e showde qualificações:
<%= @qualificacao.cliente_id %>
<%= @qualificacao.cliente.nome %>
<%= @qualificacao.restaurante_id %>
<%= @qualificacao.restaurante.nome %>
<td><%= qualificacao.cliente_id %></td> <td><%= qualificacao.restaurante_id %></td>
<td><%= qualificacao.cliente.nome %></td> <td><%= qualificacao.restaurante.nome %></td>
Por fim, vamos utilizar o FormHelper hidden_field para permitir a qualificação de um restaurante a partir da view show de um cliente ou de um restaurante. No entanto, ao fazer isso, queremos que não seja necessário a escolha de cliente ou restaurante. Para isso:
<p> <%= f.label :cliente_id %><br /> <%= f.collection_select(:cliente_id, Cliente.order('nome'), :id, :nome, {:prompt => true}) %> </p>
<% if @qualificacao.cliente %> <%= f.hidden_field 'cliente_id' %> <% else %> <p><%= f.label :cliente_id %><br /> <%= f.collection_select(:cliente_id, Cliente.order('nome'), :id, :nome, {:prompt => true}) %></p> <% end %>
<p> <%= f.label :restaurante_id %><br /> <%= f.collection_select(:restaurante_id, Restaurante.order('nome'), :id, :nome, {:prompt => true}) %> </p>
<% if @qualificacao.restaurante %> <%= f.hidden_field 'restaurante_id' %> <% else %> <p><%= f.label :restaurante_id %><br /> <%= f.collection_select(:restaurante_id, Restaurante.order('nome'), :id, :nome, {:prompt => true}) %></p> <% end %>
<%= link_to "Nova qualificação", :controller => "qualificacoes", :action => "new", :cliente => @cliente %>
<%= link_to "Qualificar este restaurante", :controller => "qualificacoes", :action => "new", :restaurante => @restaurante %>
if params[:cliente] @qualificacao.cliente = Cliente.find(params[:cliente]) end if params[:restaurante] @qualificacao.restaurante = Restaurante.find(params[:restaurante]) end
Podemos notar que nossas actions, por exemplo a index, fica muito parecida com a action index de outros controladores, mudando apenas o nome do modelo em questão.
#qualificacoes_controller def index @qualificacoes = Qualificacao.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @qualificacoes } end end #clientes_controller def index @clientes = Cliente.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @clientes } end end
Normalmente precisamos fazer exatamente a mesma ação para formatos iguais e por isso acabamos repetindo o mesmo bloco de respond_to nas actions. Para solucionar esse problema, no rails 3 acrescentaram o método respond_to nos controllers e o método respond_with nas actions. Veja o exemplo:
class ClientesController < ApplicationController respond_to :html, :xml # GET /clientes # GET /clientes.xml def index @clientes = Cliente.all respond_with @clientes end # GET /clientes/1 # GET /clientes/1.xml def show @cliente = Cliente.find(params[:id]) respond_with @cliente end ... end
Dessa forma estamos dizendo para o rails que esse controller irá responder para os formatos html e xml, dentro da action basta eu dizer qual objeto é pra ser usado. No caso da action index, se a requisição pedir o formato html, o rails simplesmente vai enviar a chamada para o arquivoviews/clientes/index.html.erb e a variável @clientes estará disponível lá. Se a requisição pedir o formato xml, o rails fará exatamente o mesmo que estava no bloco de respond_to que o scaffold criou, vai renderizar a variável @clientes em xml. O bloco de código acima é equivalente ao gerado pelo scaffold:
class ClientesController < ApplicationController # GET /clientes # GET /clientes.xml def index @clientes = Cliente.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @clientes } end end # GET /clientes/1 # GET /clientes/1.xml def show @cliente = Cliente.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @cliente } end end ... end
Veja na imagem como ficaria o ClientesController usando essa outra maneira de configurar os controllers.
Xo สล็อตออนไลน์ โปรสล็อต XO เกมออนไลน์ทำเงินยอดฮิตเกมสล็อต xopg.net คือเกมทำเงิน reeffutures2018 ผ่านทางออนไลน์อย่างหนึ่ง ที่เล่นง่าย และได้เงินไว แถมยังลงทุนด้วยเงินน้อย mavoixtavoie ทำเงินได้ตลอดเวลา ซึ่งหลายคนอาจได้เคยเห็นรีวิวเรื่องของ สล็อต xo สล็อตออนไลน์ ไว้มากมาย เทคนิคสล็อต ทั้งเรื่องการเล่นแล้วได้เงิน herbalpertpresents และเล่น สล็อต แล้วไม่ได้เงิน นั่นเองค่ะ ซึ่งการที่คุณจะเล่นได้เงินหรือไม่ได้เงินนั้น essentialsforasoul ส่วนหนึ่งก็เป็นในเรื่องของดวงเข้ามาเกี่ยวด้วย northbristol เพราะสล็อตเป็นเกมออนไลน์เสี่ยงโชค ทดลองเล่น xo เกมหนึ่งซึ่งจะมีสูตร หรือเทคนิคเข้ามาช่วย gclub เพื่อโกงดวงอยู่เสมอซึ่งในเว็บของเรา สมัคร xo ก็มีมาแนะนำไว้ให้เห็นกันมากมายหลายสูตร