Я новичок в рубинах и рельсах и боролся с этой проблемой в течение нескольких дней. Я уже искал ответ, но не смог найти решение.Rails принадлежит_от ассоциации возвращает nil в представлении
У меня есть связь «много-ко-многим» между играми, тикерами и игроками с помощью has_many: через объединение. Соответствующие декларации ассоциаций могут выглядеть так:
class Game < ActiveRecord::Base
has_many :tickers, :dependent => :destroy
has_many :players, :through => :tickers
end
class Ticker < ActiveRecord::Base
belongs_to :games
belongs_to :players
end
class Player < ActiveRecord::Base
has_many :tickers, :dependent => :destroy
has_many :games, :through => :tickers
end
Это означает, что в каждой игре есть много тикеров. У каждого Тикера есть один игрок. Наконец, игра с элементами тикер может выглядеть следующим образом:
Команда 1 Команда 2 против
00:30 | цель | Игрок 1
01:30 | цель | Игрок 2 ...
Я хочу показать имя игрока в игровом режиме. Это мое приложение/просмотров/игры/show.html.erb:
<p id="notice"><%= notice %></p>
<p>
<b>Home:</b>
<%= @game.home_team.team_name %>
</p>
<p>
<b>Away:</b>
<%= @game.away_team.team_name %>
</p>
<table>
<tr>
<th>Activity</th>
<th>Player</th>
<th>Time</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @tickers.each do |ticker| %>
<tr>
<td><%= ticker.activity_id %></td>
<td><%= ticker.players.player_name %></td>
<td><%= ticker.time %></td>
<td><%= link_to 'Show', ticker %></td>
<td><%= link_to 'Edit', edit_ticker_path(ticker) %></td>
<td><%= link_to 'Destroy', ticker, confirm: 'Are you sure?', method: :delete %> </td>
</tr>
<% end %>
</table>
Вот моя проблема:
<%= ticker.players.player_name %>
дает мне ошибку
неопределенный метод `PLAYER_NAME» для ноль: NilClass
Но
<%= ticker.player_id %>
дает мне правильный идентификатор игрока. Игрок с этим идентификатором существует и имеет имя игрока. Таким образом, это не может быть причиной. Но я получаю ноль при звонке:
<%= ticker.players %>
Что пошло не так? Спасибо за помощь!
Lars
PS: Некоторые больше информации о моем коде:
приложение/контроллеры/games_controller.rb:
def show
@game = Game.find(params[:id])
@tickers = @game.tickers
respond_to do |format|
format.html # show.html.erb
format.json { render json: @game }
end
end
Моя схема базы данных:
create_table "games", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "players", :force => true do |t|
t.string "player_name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "tickers", :force => true do |t|
t.integer "activity_id"
t.integer "player_id"
t.integer "time"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "game_id"
end
Это как я создаю новый экземпляр тикера (пока):
приложение/просмотров/игры/show.html.erb:
<%= link_to 'New Ticker', new_ticker_path(:game_id=>@game.id) %>
приложение/просмотров/линеечки/_form.html.erb
<%= form_for(@ticker) do |f| %>
<% if @ticker.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@ticker.errors.count, "error") %> prohibited this ticker from being saved:</h2>
<ul>
<% @ticker.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.hidden_field :game_id, :value => params[:game_id] %>
</div>
<div class="field">
<%= f.label :activity_id %><br />
<%= f.number_field :activity_id %>
</div>
<div class="field">
<%= f.label :player_id %><br />
<%= f.number_field :player_id %>
</div>
<div class="field">
<%= f.label :time %><br />
<%= f.number_field :time %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
приложение/контроллеры/tickers_controller.rb
def new
@ticker = Ticker.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @ticker }
end
end
def create
@ticker = Ticker.new(params[:ticker])
respond_to do |format|
if @ticker.save
format.html { redirect_to @ticker, notice: 'Ticker was successfully created.' }
format.json { render json: @ticker, status: :created, location: @ticker }
else
format.html { render action: "new" }
format.json { render json: @ticker.errors, status: :unprocessable_entity }
end
end
end
Да. Вот и все. Но не могли бы вы объяснить мне, почему это единственное и в другом случае множественное число? – Lars
, потому что объект всегда может принадлежать только «одному» родительскому, а не многим, и имеет «один или несколько» детей. если вы все еще хотите, чтобы существующий код работал, то вы можете добавить метод с именем «игры» и «игроки» в класс и получить «родительский», используя свой идентификатор, но в конечном итоге это не имеет смысла. –
Спасибо за ваш ответ :) – Lars