#ruby-on-rails #associations
#ruby-on-rails #ассоциации
Вопрос:
Схема:
create_table "reports", :force => true do |t|
t.integer "user_id"
t.string "apparatus"
t.string "capt"
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "login", :limit => 40
t.string "name", :limit => 100, :default => ""
t.string "email", :limit => 100
t.string "crypted_password", :limit => 40
t.string "salt", :limit => 40
t.datetime "created_at"
t.datetime "updated_at"
t.string "remember_token", :limit => 40
t.datetime "remember_token_expires_at"
t.string "rank"
t.integer "shift"
t.integer "access"
end
пользовательская модель:
Class User < ActiveRecord::Base
has_many :reports
# bunch of other stuff thats not important
end
модель отчета:
Class Report < ActiveRecord::Base
belongs_to :user
end
просмотры / отчеты / индекс
<% @reports.each do |report| %>
<tr>
<td><%= report.user_id %></td> # ****THIS IS THE LINE IN QUESTION****
<td><%= report.apparatus %></td>
<td><%= report.capt %></td>
<td><%= report.body %></td>
<td><%= link_to 'Show', report %></td>
<td><%= link_to 'Edit', edit_report_path(report) %></td>
<td><%= link_to 'Destroy', report, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
Я хотел бы иметь возможность отображать имя пользователя, создавшего отчет. Я предполагал, что объявление ассоциаций belongs_to и has_many сделает это возможным, написав report.user.name или что-то в этом роде. Где я ошибся?
Комментарии:
1. хорошо, проблема заключалась в том, что в моей таблице был один кортеж, у которого не было идентификатора пользователя. поэтому он зависал, пытаясь найти метод name на nil. Я задница.
Ответ №1:
Я на 99% уверен, что это связано с тем, что в одном или нескольких ваших отчетах нет связанного пользователя. Попробуйте
<%= report.user.name rescue "none" %>
Если в поле user_id в отчете нет значения, то report.user
будет возвращен nil. Это report.user.name
было бы похоже на вызов nil.name
, который вызывает ошибку.
ОБНОВЛЕНИЕ: вот лучший способ:
<%= report.user.try(:name) %>
Ответ №2:
Вы можете сделать:
<%= report.user.name %>
Но для повышения эффективности в вашем контроллере вы можете выполнить объединение, чтобы получить имя пользователя в том же запросе, который использовался для получения @reports .
Этот запрос может выглядеть примерно так:
@reports = Report.select("reports.id as id, reports.apparatus as apparatus, reports.capt as capt, reports.body as body, users.name as user_name").joins("LEFT JOIN `users` ON `users`.`id` = `reports`.`user_id`")
Тогда ваш вывод будет выглядеть так:
<%= report.user_name %>
Комментарии:
1. <%= report.user.name %> не работает. он выдает «имя неопределенного метода»»
2. хорошо, проблема заключалась в том, что в моей таблице был один кортеж, у которого не было идентификатора пользователя. поэтому он зависал, пытаясь найти метод name на nil. Я задница.
3. я немного опоздал, но рад, что вы это поняли!