Rotaie: impalcatura per fare automaticamente una relazione uno-a-molti
-
20-08-2019 - |
Domanda
Non sono sicuro se sto leggendo questo giusto, ma sembra che Scaffold non farà una relazione uno-a-molti nella sua interezza. Ad esempio, se creo messages
con impalcatura e quindi voglio comments
su quelli message
(uno comment
- & Gt; molti new
), devo passare attraverso e cambiare tutto. Ad esempio, devo cambiarlo nella @message
vista <=>
<% form_for(@comment) do |f| %>
a questo
<% form_for([@message, @comment]) do |f| %>
e quindi modifica l'azione per impostare <=> var ... tra le altre cose.
Attualmente non è possibile farlo automaticamente con Scaffold, giusto?
Soluzione
Questo è vero, ma non è la fine della storia. Esistono almeno due alternative a Scaffold che funzionano entrambe abbastanza bene e rilevano automaticamente le relazioni tra le classi (in base agli indicatori delle relazioni ActiveRecord come has_many). Una di queste alternative è Streamlined e l'altra è ActiveScaffold .
Sono principalmente utili per l'immissione di dati richiesti dal sistema che non sono dati inseriti dall'utente. Ad esempio, li uso per attività amministrative su tabelle in cui non ha senso costruire un'interfaccia utente completa per CRUD quando una delle alternative dell'impalcatura farà il lavoro bene per una funzione usata raramente. Non vorrai usarli per i commenti sui messaggi.
Altri suggerimenti
Sì. L'impalcatura funziona per un modello e relativo controller. Non si occupa o lavora con le relazioni.
L'obiettivo principale di Scaffold è far funzionare CRUD su un modello usando un controller e viste correlate. È tutto. Qualsiasi altro requisito come le relazioni deve essere codificato manualmente.
Nota che esistono progetti come Hobo per Rails che ti consentono di mantenere i tuoi campi e le tue associazioni all'interno del modello stesso . Non puoi impilare le associazioni, ma è abbastanza vicino.
Finisci per pagare questo zucchero avendo molte più applicazioni costruite dietro la schiena. Invece di lanciare il tuo, di solito stai sottraendo ciò di cui hai bisogno da una grande banca di comportamenti precompilati.
Non è necessario un pesante framework di amministrazione rotaie per far funzionare le relazioni uno-a-molti.
È possibile utilizzare le impalcature per raggiungere la maggior parte del percorso.
Un po 'più di lavoro nel controller e nella vista _form ti porterà il resto del percorso.
Ecco come ...
Story: Select a beer for a developer
In order to select a beer for a developer
As an admin
I want a mainly scaffolded interface to select that beer
Scenario 1: Select beer for new developer
Given I have clicked the <new> button and entered the developer's name
When I click the beer dropdown
Then I should be presented with a list of beers to choose from
And that beer will be saved when I click <ok>
Scenario 2: Select a different beer for existing developer
Given I have clicked the <edit> button on the index page for a particular developer
When I click the beer dropdown
Then I should be presented with a list of beers to choose from
And that beer will be saved when I click <ok>
Supponendo che abbiamo una birre tabella:
create_table "beers", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
E una tabella degli sviluppatori con una chiave esterna (beer_id) che fa riferimento alla tabella delle birre:
create_table "developers", force: true do |t|
t.string "name"
t.integer "beer_id"
t.datetime "created_at"
t.datetime "updated_at"
end
Possiamo usare le impalcature per creare entrambe le tabelle:
$ rails g nome della birra dell'impalcatura
$ rails g nome sviluppatore scaffold beer_id: intero
Il comando scaffold crea i controller e le viste per ciascun modello.
Dovremo modificare i nostri controller e le viste un po 'per ottenere il menu a discesa per selezionare una birra per ogni sviluppatore:
app / views / sviluppatori / _form.html.erb
Sostituisci il campo di testo generato e l'etichetta per beer_id con il seguente:
<div class="field">
<%= f.label :beer_id %><br />
<%= collection_select(:developer, :beer_id, @beers, :id, :name, {:prompt => false}) %>
</div>
app / controllers / developer_controller.rb
Modifica i metodi nuovi e di modifica del controller:
# GET /developers/new
def new
@developer = Developer.new
@beers = Beer.all
respond_to do |format|
format.html # new.html.erb
end
end
# GET /developers/1/edit
def edit
@beers = Beer.all
respond_to do |format|
format.html # new.html.erb
end
end
Schermate
Note
L'impalcatura delle rotaie è eccezionale. Guarda tutti i file che crea per te:
$ be rails g scaffold beer name
invoke active_record
create db/migrate/20140912144218_create_beers.rb
create app/models/beer.rb
invoke rspec
create spec/models/beer_spec.rb
invoke factory_girl
create spec/factories/beers.rb
invoke resource_route
route resources :beers
invoke scaffold_controller
create app/controllers/beers_controller.rb
invoke erb
create app/views/beers
create app/views/beers/index.html.erb
create app/views/beers/edit.html.erb
create app/views/beers/show.html.erb
create app/views/beers/new.html.erb
create app/views/beers/_form.html.erb
invoke rspec
create spec/controllers/beers_controller_spec.rb
create spec/views/beers/edit.html.erb_spec.rb
create spec/views/beers/index.html.erb_spec.rb
create spec/views/beers/new.html.erb_spec.rb
create spec/views/beers/show.html.erb_spec.rb
create spec/routing/beers_routing_spec.rb
invoke rspec
create spec/requests/beers_spec.rb
invoke helper
create app/helpers/beers_helper.rb
invoke rspec
create spec/helpers/beers_helper_spec.rb
invoke jbuilder
create app/views/beers/index.json.jbuilder
create app/views/beers/show.json.jbuilder
invoke assets
invoke coffee
create app/assets/javascripts/beers.js.coffee
invoke scss
create app/assets/stylesheets/beers.css.scss
invoke scss
create app/assets/stylesheets/scaffolds.css.scss
Tutto quello che devi fare è sapere quali file modificare quando desideri più delle operazioni CRUD di base.
Spero che sia d'aiuto. ~ Lex
Le impalcature sono impalcature. Quando si desidera qualcosa di diverso da un CRUD su una tabella (che è / cosa è uno scaffold), è necessario modificare il codice di impalcatura generato, o rollare il proprio.