2013-06-01 33 views
16

Tôi có mối quan hệ giữa 2 kiểu trong ứng dụng đường ray của mình. Tôi đã tránh xa tiêu chuẩn về cách thực hiện mối quan hệ khi tôi sử dụng một trường khác làm khóa chính và quy ước đặt tên khác nhau. Làm như vậy dẫn đến mối quan hệ dường như không được thiết lập. Tôi muốn hiểu tại sao.Rails thuộc về has_many với khóa ngoài tùy chỉnh

Đây là phiên bản cắt giảm của các mô hình của tôi:

class Player < ActiveRecord::Base 
    set_primary_key "alias" 
    attr_accessible :alias, :avatar 
    has_many :player_sessions, :foreign_key => "player_alias", :class_name => "PlayerSession" 
end 

class PlayerSession < ActiveRecord::Base 
    attr_accessible :player_alias, :total_score 
    belongs_to :player, :foreign_key => "player_alias", :class_name => "Player" 
end 

Mô hình Player có trường alias đó là tên người dùng trong ứng dụng của tôi. Tôi muốn tên người dùng hoạt động như khóa chính vì nó là duy nhất và sẽ dễ dàng di chuyển dữ liệu hơn và duy trì mối quan hệ.

Ban đầu tôi chỉ có mô hình PlayerSession với dữ liệu đã được điền, nhưng khi ứng dụng của tôi phát triển, tôi đã thêm mô hình Trình phát và chỉ cần chèn một hàng với cùng một alias.

Trong show quan điểm của Player Tôi có đoạn code sau:

Player Sessions: 
<% @player.player_sessions do |player_session| %> 
<ul> 
    <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li> 
</ul> 

Khi tôi cố gắng truy cập vào các trang nó đơn giản không hiển thị các thông tin.

Thông tin khác tôi có thể thêm là tôi chưa thêm bất kỳ mối quan hệ nào trong cơ sở dữ liệu.

Tôi vẫn còn mới đến đường ray và vẫn chơi đùa với nó. Bất kỳ ý kiến ​​nào liên quan đến tiêu chuẩn viết mã (ngoài việc trả lời câu hỏi) đều được hoan nghênh.


Cập nhật tôi đã thực hiện đề nghị Babur Usenakunov bằng cách thêm các primary_key tùy chọn trong các mô hình:

class Player < ActiveRecord::Base 
    set_primary_key "alias" 
    attr_accessible :alias, :avatar 
    has_many :player_sessions, :primary_key => "alias", :foreign_key => "player_alias", :class_name => "PlayerSession" 
end 

class PlayerSession < ActiveRecord::Base 
    attr_accessible :player_alias, :total_score 
    belongs_to :player, :primary_key => "alias", :foreign_key => "player_alias", :class_name => "Player" 
end 

Ngoài ra để kiểm tra dữ liệu được hợp lệ tôi mua lại danh sách PlayerSession thủ công:

Mã được triển khai trong bộ điều khiển:

@player_sessions = PlayerSession.where("player_alias = ?", params[:id]) 
.210

Mã thực hiện theo quan điểm (mà kết quả đầu ra dữ liệu):

<% @player_sessions.each do |player_session| %> 
<ul> 
    <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li> 
</ul> 
<% end %> 
+1

Tôi không chắc chắn nhưng có thể bạn cũng nên chuyển khóa chính trong các tùy chọn. Ví dụ. 'has_many: player_sessions,: primary_key => 'alias',: foreign_key => 'player_alias': class_name => 'PlayerSession'' và' thuộc_to: player,: primary_key =>' alias ',: foreign_key => "player_alias", : class_name => "Player" ' –

+0

Đã thử nó theo cách đó nhưng vẫn không hoạt động – Drahcir

+0

@ Drahcir, tôi có khuynh hướng nghĩ rằng gợi ý của Babur Usenakunov nên đã hoạt động. '@ Player.player_sessions' trở lại sau khi bạn thử đề xuất của họ là gì? – Sun

Trả lời

1

Nếu bảng PlayerSession của bạn có một cột tên là alias thì chính nước ngoài của bạn cũng nên alias, không player_alias. Tôi khuyên bạn nên thận trọng khi sử dụng bí danh như một ngoại lệ: nếu người chơi của bạn có thể/quyết định thay đổi bí danh của mình thì tất cả các bản ghi PlayerSession trong cơ sở dữ liệu của bạn sẽ trở thành không hợp lệ và yêu cầu cập nhật. Sử dụng tham số không thay đổi như player_id sẽ thích hợp hơn khi sử dụng cột bí danh hiện tại IMHO.

+0

Bí danh là tên người dùng của người chơi. Vì vậy, nó không thể thay đổi. Nó giống như quyết định thay đổi địa chỉ email của bạn và giữ tất cả các email của bạn – Drahcir

12

Tôi đã giải quyết vấn đề này, đó là vấn đề của việc thêm each trong vòng lặp tôi thực hiện trong giao diện:

<% @player.player_sessions.each do |player_session| %> 
<ul> 
    <li><h4>Highest Score:</h4> <%= player_session.total_score %> </li> 
</ul>  
<% end %> 

Sau khi chơi xung quanh một chút, tôi nhận ra tôi đã không cần phải thêm primary_key ở một trong các khung nhìn và chỉ để lại tùy chọn khóa ngoài trong mô hình Player.

class Player < ActiveRecord::Base 
    set_primary_key "alias" 
    attr_accessible :alias, :avatar 
    has_many :player_sessions, :foreign_key => "player_alias", :class_name => "PlayerSession" 
end 

class PlayerSession < ActiveRecord::Base 
    attr_accessible :player_alias, :total_score 
    belongs_to :player, :class_name => "Player" 
end 
+0

Bạn có thể giúp tôi với cái này không ?? http://stackoverflow.com/questions/25047920/rails-belongs-to-with-custom-column-name – mariowise

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