2017-04-18 17 views
1

Ich rüstete ein einfaches Beispiel, um ein Problem zu veranschaulichen, das ich habe. In diesem Beispiel habe ich ein Raumschiff und einen Piloten. Ich möchte dem Raumschiff bei der Erstellung einen vorhandenen Piloten zuweisen können.Model (# ...) erwartet, bekam String (# ...) Fehler bei der Verwendung von Select-Tag

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 

Raumschiffen/_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 

params Hash

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

Und ich bekomme diese Fehlermeldung

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

ich sehe, dass mein Pilot als String in der Hash gesendet wird, aber Ich finde nicht, wie ich es anders machen soll.

+2

10 Sie können ein Objekt nicht so an den params-Hash übergeben. Sie könnten versuchen, die ID dieses Objekts zu senden und später das Objekt in Ihrem Ziel zu finden. –

Antwort

4

Verwenden Sie Sammlung auswählen und nur die Pilot-ID zurückgeben.

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

Beachten Sie, dass Sie benötigen, um Ihre starship_params

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

ein attr_accessor hinzufügen zu ändern: pilot_id

class Starship < ApplicationRecord 
    attr_accessor :pilot_id 

Ändern Sie bitte Ihre erstellen, wie folgt ...

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

Ich habe das versucht, aber ich bekomme diesen Fehler jetzt undefined Methode 'pilot_id 'für # Meinst du? Pilot ". Irgendeine Idee, wo ich vielleicht einen Fehler gemacht habe? – LRP

+0

Ah, richtig, tut mir leid, es ist ein 'has_one'. Antwort geändert. Prost – SteveTurczyn

+0

Funktioniert perfekt Vielen Dank – LRP

0

Sie haben eine eins zu eins op Beziehung. Wenn Sie nur alle Piloten auflisten, können diese überschrieben werden. Es ist besser, einen neuen Pilot zu erstellen, als einen aus der ganzen Liste zuzuweisen.

Noch, wenn Sie diesen Code verwenden möchten. Denken Sie daran, dass Sie auch Pilot.pluck(:id) unten verwenden können, wenn Sie Pilot übertragen möchten.

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

Jetzt in Ihrem starship_controller Methode erstellen

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 

Ihr starker params sein sollte

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

Hope this helps ...

+0

Ich habe 'Konnte Pilot ohne eine ID nicht finden'. Ich habe versucht mit 'f.select: pilot' und' params.require (: starship) .permit (: name,: pilot) 'stattdessen und habe den ursprünglichen Fehler wieder – LRP

0

Ersetzen Sie einfach unten Code schreiben mit deinem Code und du bist gut zu gehen.

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

Dies wird Pilotenname in der Auswahl Dropdown zeigen und insbesondere Piloten id sparen beim Speichern.

+0

Immer noch der gleiche Fehler hier, aber mit diesem Hash jetzt' { "name" => "Nostromo", "pilot" => "2"} ' – LRP

Verwandte Themen