2013-05-31 4 views
14

İki modelle basit bir alıştırma yapıyorum.Raylar - Yabancı Anahtar Referanslarını bir formda görüntüleme

 
rails g scaffold sport name:integer 
rails g scaffold team name:integer fans:integer sport:references 

olarak tanımlanan Spor ve Takımlar, (Not: Ben iskeleyi kullanıyorum sebebi hızla parçalarıyla/öğrenebilirim böylece deney prototip olduğu henüz aşina değilim)

Sorun olmasıdır (yabancı anahtar referans yani) benim "spor" ... bu yüzden buna o garip #<blahl blah> notasyonu var şu enter image description here

gibi gösteriyor

<%= form_for(@team) do |f| %> 
    <% if @team.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@team.errors.count, "error") %> prohibited this team from being saved:</h2> 

     <ul> 
     <% @team.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

    <div class="field"> 
    <%= f.label :name %><br /> 
    <%= f.text_field :name %> 
    </div> 
    <div class="field"> 
    <%= f.label :fans %><br /> 
    <%= f.number_field :fans %> 
    </div> 
    <div class="field"> 
    <%= f.label :sport %><br /> 
    <%= f.text_field :sport %> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

Bir satırı @team.sport.name olarak değiştirmeyi denedim ancak bir hatayla sonuçlanır undefined method 'Ice Hockey' for #<Team:0x3e7e040> ... Buraya gelen adın nasıl doğru şekilde görüntüleneceği konusunda herhangi bir fikir var mı?

cevap

29

Varolan bir nesneyi referans almak için text_field kullanıyorsunuz, Spor seçenekleri select ve burada daha uygun olacaktır. değiştirilemez zorunda olduğu

budur:

<div class="field"> 
    <%= f.label :sport %><br /> 
    <%= f.text_field :sport %> 
</div> 

için:

<div class="field"> 
    <%= f.label :sport %><br /> 
    <%= f.select :sport_id, options_for_select(Sport.all.map{|s|[s.name, s.id]}) %> 
</div> 

f.select HTML seçkin kutu üretecektir, seçenekler DB spor bana olacak.

bu konuda bazı belgeler:

controller içerisinde bir değişken @sports ayarlayabilir ve görünümlerde sonra diyoruz olacaktır Bir temizleyici yolu :

# in controller 
def edit 
    @sports = Sport.scoped 
    #... 

# in edit view 
<div class="field"> 
    <%= f.label :sport %><br /> 
    <%= f.select :sport_id, options_for_select(@sports.map{ |s| [s.name, s.id] }) %> 
</div> 

Additionnal bilgiler: select için bir seçenek "ön seçim", sen options_for_select yardımcı ikinci argüman olarak geçmek zorunda istiyorsanız:

options_for_select(@sports.map{ |s| [s.name, s.id] }, params[:sport_id]) 
# this will select by default the option that matches the value of params[:sport_id] 
+0

teşekkür @MrYoshiji . Başlamak için ilk öneriyi deniyorum ve değerler seçim kutusunda doğru görünüyor. Ancak, kaydetmeye çalışırken "ActiveModel :: MassAssignmentSecurity :: Error" alıyorum, "Korunan öznitelikleri toplu atayamazsınız: sport_id" – Ricky

+2

": sport_id" ifadesini benim için attr_accessors'a ekleyerek çalışıyorum. teams_controller. Bunu yapmanın doğru yolu bu muydu? Ayrıca 2. yöntemi denedim ve işe yarıyor ama nedenini anlamıyorum. 'Sport.scoped' nedir? Neden sadece 'düzenleme' yönteminde gereklidir? Örnek, 'new' metodu da aynı' _form.html.erb' görünümünü paylaşır, ancak ben orada 'ssports = Sport.scoped' için arama yapmıyorum ama hala çalışıyor ... Herhangi bir anlayış için teşekkürler – Ricky