2017-04-18 6 views
1

J'ai créé un exemple simple pour illustrer un problème que j'ai. Dans cet exemple, j'ai un vaisseau spatial et un pilote. Je veux être en mesure d'affecter un pilote existant au vaisseau spatial lors de la création.Modèle (# ...) attendu, obtenu Chaîne (# ...) erreur lors de l'utilisation de la balise de sélection

starship.rb

class Starship < ApplicationRecord 
    has_one :pilot 

    validates :name, presence: true 
end 

pilot.rb

class Pilot < ApplicationRecord 
    belongs_to :starship, optional: true 

    validates :name, presence: true 
end 

starships/_form.html.erb

<div class="field"> 
    <%= f.label :pilot %> 
    <%= f.select :pilot, Pilot.all %> 
</div> 

starships_controller.rb

def starship_params 
    params.require(:starship).permit(:name, :pilot) 
    end 

de hachage

{"name"=>"Nostromo", "pilot"=>"#<Pilot:0x007f85ff547f90>"} 

Et je reçois cette erreur

Pilot(#70106745549840) expected, got String(#70106709663840) 

Je vois que mon pilote est envoyé comme une chaîne dans le hachage, mais Je ne trouve pas comment je suis supposé le faire autrement.

+2

Vous ne pouvez pas passer un objet au paramètre Hash comme ça. Vous pourriez essayer d'envoyer le 'id 'de cet objet et trouver plus tard que l'objet dans votre destination. –

Répondre

4

Utilisez collection sélectionnez et renvoyez uniquement l'ID du pilote.

<%= f.collection_select(:pilot_id, Pilot.all, :id, :name) %> 

Notez que vous aurez besoin de changer vos starship_params

def starship_params 
    params.require(:starship).permit(:name, :pilot_id) 
    end 

Ajouter un attr_accessor pour: pilot_id

class Starship < ApplicationRecord 
    attr_accessor :pilot_id 

Modifier votre créer comme suit ...

def create 
    @starship = Starship.new(starship_params) 
    @starship.pilot = Pilot.find(@starship.pilot_id) 
    respond_to do |format| 
    ... 
+0

J'ai essayé ceci mais j'ai cette erreur maintenant 'méthode non définie' pilote_id 'pour # Vouliez-vous dire? pilote ». Toute idée d'où j'ai pu faire une erreur? – LRP

+0

Ah, c'est vrai, désolé, c'est un 'has_one'. Réponse modifiée Cheers – SteveTurczyn

+0

Fonctionne parfaitement merci beaucoup – LRP

0

Vous avez un op de un à un relationnelle. La simple énumération de tous les pilotes peut les écraser. Il est préférable de créer un nouveau pilote que d'en assigner un de la liste entière.

Toujours si vous voulez utiliser essayez ce code. Rappelez-vous que vous pouvez également utiliser Pilot.pluck(:id) ci-dessous si vous voulez transférer le pilote.

<div class="field"> 
    <%= f.label :pilot_id %> 
    <%= f.select :pilot_id, Pilot.where('starship_id is NULL').pluck(:id) %> 
</div> 

Maintenant dans votre starship_controller méthode de création écrire

def create 
    @starship = Starship.new(starship_params) 
    pilot = @starship.build_pilot 
    pilot.id= params[:starship][:pilot_id] 
    pilot.reload 
    respond_to do |format| 
     if @starship.save 
     format.html { redirect_to root_path, notice: 'Starship successfully created.' } 
     else 
     format.html { redirect_to root_path, notice: 'Error occured.' } 
     end 
end 

Vos fortes params devraient être

def starship_params 
    params.require(:starship).permit(:name, :pilot_id) 
end 

Hope this helps ...

+0

J'ai 'Impossible de trouver un pilote sans ID». J'ai essayé avec 'f.select: pilot' et' params.require (: starship) .permit (: nom,: pilot) 'à la place et ai encore obtenu l'erreur originale – LRP

0

Il suffit de remplacer le code ci-dessous avec ton code et vous êtes bon à faire.

<%= f.label :pilot %> 
<%= f.select :pilot, Pilot.all.map{ |p| [p.name, p.id] } %> 

Cela montrera le nom du pilote dans le menu déroulant de sélection et économisera l'id pilote particulier lors de l'enregistrement.

+0

Toujours eu la même erreur ici mais avec ce hash maintenant' { "name" => "Nostromo", "pilot" => "2"} ' – LRP