web-dev-qa-db-fra.com

Comment avoir un champ <select> déroulant dans un formulaire Rails?

Je crée un échafaudage -

Rails g scaffold Contact email:string email_provider:string 

mais je veux que le fournisseur de messagerie soit un menu déroulant (avec les options gmail/yahoo/msn) et non un champ de texte. Comment puis-je faire ceci ?

71
iCyborg

Vous pouvez jeter un oeil à la documentation Rails . Quoi qu'il en soit, sous votre forme:

  <%= f.collection_select :provider_id, Provider.order(:name),:id,:name, include_blank: true %>

Comme vous pouvez le deviner, vous devez prédéfinir les fournisseurs de courrier électronique dans un autre modèle, Provider, afin de pouvoir les sélectionner.

83
R Milushev

Ou pour des options personnalisées

<%= f.select :desired_attribute, ['option1', 'option2']%>
44
Fdwillis

Vous créez la collection dans le contrôleur Contact -

app/controllers/contacts_controller.erb 

Ajouter

@providers = Provider.all.by_name

à la nouvelle, créer et éditer des méthodes, en utilisant une portée pour le by_name dans le modèle Provider - app/models/provider.rb - pour l'ordre par nom

scope by_name  order(:name)

Puis dans la vue - app/views/contacts/_form.html.erb - vous utilisez

<%= f.collection_select :provider_id, @providers, :id, :name, include_blank: true %>

Pour les Rails formulaires, je vous recommande également vivement de consulter un générateur de formulaire tel que simple_form - https://github.com/plataformatec/simple_form - qui fera le gros du travail.

15
Michael Durrant

C'est un long chemin, mais si vous n'avez pas encore implémenté, vous pouvez créer vos modèles de cette façon. La méthode ci-dessous décrit la modification d'une base de données existante.

1) Créez un nouveau modèle pour les fournisseurs de messagerie:
$ Rails g model provider name

2) Ceci créera votre modèle avec une chaîne de nom et des horodatages. Il crée également la migration que nous devons ajouter au schéma avec:
$ rake db:migrate

3) Ajoutez une migration pour ajouter l'ID de fournisseur au contact:
$ Rails g migration AddProviderRefToContacts provider:references

4) Parcourez le fichier de migration pour vérifier qu'il a l'air correct et migrez-le aussi:
$ rake db:migrate

5) Bon, maintenant nous avons un provider_id, nous n'avons plus besoin de la chaîne email_provider originale:
$ Rails g migration RemoveEmailProviderFromContacts

6) Dans le fichier de migration, ajoutez la modification qui ressemblera à:

class RemoveEmailProviderFromContacts < ActiveRecord::Migration
  def change
    remove_column :contacts, :email_provider
  end
end

7) Une fois que cela est fait, migrez le changement:
$ rake db:migrate

8) Profitons de ce moment pour mettre à jour nos modèles:
Contact: belongs_to :provider
Fournisseur: has_many :contacts

9) Ensuite, nous configurons la logique de menu déroulant dans le partiel _form.html.erb dans les vues:

  <div class="field">
    <%= f.label :provider %><br>
    <%= f.collection_select :provider_id, Provider.all, :id, :name %>
  </div>

10) Enfin, nous devons ajouter les provders eux-mêmes. Une façon de faire serait d’utiliser le fichier de départ:

Provider.destroy_all

gmail = Provider.create!(name: "gmail")
yahoo = Provider.create!(name: "yahoo")
msn = Provider.create!(name: "msn")

$ rake db:seed

8
phobos

S'il vous plaît jeter un oeil ici

Vous pouvez aussi utiliser la balise Rails ou utiliser des balises HTML simples .

balise Rails

<%= select("Contact", "email_provider", Contact::PROVIDERS, {:include_blank => true}) %>

* au-dessus de la ligne de code deviendrait du code HTML (balise HTML), trouvez-le ci-dessous *

balise HTML

<select name="Contact[email_provider]">
  <option></option>
  <option>yahoo</option>
  <option>gmail</option>
  <option>msn</option>
</select>
3

Dans votre modèle,

class Contact
  self.email_providers = %w[Gmail Yahoo MSN]
  validates :email_provider, :inclusion => email_providers
end

Sous votre forme,

<%= f.select :email_provider, 
    options_for_select(Contact.email_providers, @contact.email_provider) %>

le second argument de options_for_select aura n'importe quel email_provider actuel sélectionné.

3
konyak

Les menus déroulants utilisent l'association has_many pour l'article et la catégorie:

has_many :articles

belongs_to :category

<%= form.select :category_id,Category.all.pluck(:name,:id),{Prompt:'select'},{class: "form-control"}%>
0
sivamani

<%= f.select :email_provider, ["gmail","yahoo","msn"]%>

0
gsumk