2013-05-31 44 views
14

Tôi đang thực hiện một bài tập đơn giản với hai mô hình. Thể thao và Đội, được định nghĩa nhưĐường ray - Hiển thị Tham chiếu Khóa Ngoài ở dạng

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

(Lưu ý: Lý do tôi đang sử dụng giàn giáo đang nhanh chóng prototyping vì vậy tôi có thể học hỏi/thí nghiệm với các bộ phận Tôi không quen thuộc với chưa)

Vấn đề là của tôi "thể thao" (tức là tài liệu tham khảo chính nước ngoài) được thể hiện như sau enter image description here

Vì vậy, nó có mà lạ #<blahl blah> ký hiệu để nó ...

<%= 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 %> 

Tôi đã thử thay đổi một dòng thành @team.sport.name nhưng kết quả là lỗi undefined method 'Ice Hockey' for #<Team:0x3e7e040> ... Bất kỳ ý tưởng nào về cách hiển thị tên đúng cách từ đây ??

Trả lời

29

Bạn đang sử dụng text_field để tham chiếu một đối tượng hiện có, một select với Thao tác làm tùy chọn sẽ phù hợp hơn ở đây.

Đây là nơi mà nó phải được thay đổi:

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

Để:

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

Các f.select sẽ tạo ra một hộp chọn trong HTML, các tùy chọn sẽ cho tôi tất cả các môn thể thao trong DB của bạn.

Một số tài liệu về nó:

Một cách sạch sẽ được thiết lập một biến @sports trong điều khiển của bạn và gọi nó là sau đó trong quan điểm của bạn :

# 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> 

thông tin thêm vào một số: Nếu bạn muốn "trước khi chọn" một lựa chọn cho các lựa chọn, bạn phải vượt qua nó như là đối số thứ hai của options_for_select helper:

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

Cảm ơn @MrYoshiji . Tôi đang cố gắng đề xuất đầu tiên của bạn để bắt đầu và các giá trị xuất hiện chính xác trong hộp chọn. Tuy nhiên, tôi nhận được một 'ActiveModel :: MassAssignmentSecurity :: Error' khi cố gắng lưu, nó nói 'Không thể gán hàng loạt thuộc tính được bảo vệ: sport_id' – Ricky

+2

Tôi nhận nó hoạt động bằng cách thêm': sport_id' vào attr_accessors của tôi cho các teams_controller. Đây có phải là cách chính xác để làm điều đó không? Ngoài ra, tôi đã thử phương pháp thứ 2, và nó hoạt động, nhưng tôi không hiểu tại sao. 'Sport.scoped' là gì? Tại sao nó chỉ yêu cầu trong phương thức 'edit'? Ví dụ, phương thức 'new' cũng chia sẻ cùng một khung nhìn' _form.html.erb', nhưng tôi không gọi hàm '@sports = Sport.scoped' ở đó nhưng nó vẫn hoạt động ... – Ricky

Các vấn đề liên quan