Rails 5:重构 - 一对多关系(测试和视图)
Rails 5: Refactoring - One to Many Relationship (Tests and Views)
对 rails 有点陌生,并试图通过 Rails 文档或 rails 指南找到我一直遇到的问题的一些答案,但运气不佳,或者rails 教程。
我的目标是接受 rails 处理事情的方式,并尝试让其他开发人员以后更容易进入该项目。
问题 1:重构问题
Rails 重构实践。我不确定这是否应该放在模型或控制器中,我真的只是想知道哪些项目应该放在控制器中,哪些应该放在模型中。
第一次迭代:
<% @departments.each do |department| %>
<tr>
<td><%= department.name %></td>
<td><%= department.description %></td>
<td>
<%= library = Library.find_by(id: department.library_id).name %>
</td>
<td><%= link_to 'Show', department %></td>
<td><%= link_to 'Edit', edit_department_path(department) %></td>
<td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
这对我来说似乎是错误的,并且似乎应该将其作为后端逻辑从该部分中删除。
第二次迭代:
型号
class Department < ApplicationRecord
belongs_to :library
def get_library_name(lib_id)
library = Library.find_by(id: lib_id)
return library.name
end
end
查看
<% @departments.each do |department| %>
<tr>
<td><%= department.name %></td>
<td><%= department.description %></td>
<td>
<%= department.get_library_name(department.library_id) %>
</td>
<td><%= link_to 'Show', department %></td>
<td><%= link_to 'Edit', edit_department_path(department) %></td>
<td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
这感觉更正确,但并非完全正确,所以我不确定如何才能将其更改为更正确,特别是因为列出记录的索引视图非常相似。
我该如何重构它?
问题 2:我的测试不会通过
无论如何,我的测试没有通过。我猜这就是我使用一对多关系的方式。
test "should get index" do
get departments_url
assert_response :success
end
错误:
DepartmentsControllerTest#test_should_get_index:
ActionView::Template::Error: undefined method `name' for nil:NilClass
app/models/department.rb:6:in `get_library_name'
app/views/admin/departments/index.html.erb:21:in `block in _app_views_admin_departments_index_html_erb__1894713831414342893_57284960'
app/views/admin/departments/index.html.erb:16:in `_app_views_admin_departments_index_html_erb__1894713831414342893_57284960'
test/controllers/departments_controller_test.rb:11:in `block in <class:DepartmentsControllerTest>'
问题一:
您可以使用关联方法轻松访问关联图书馆的查询。
每当您将 belong_to :library
添加到 Department
时,您实际上只是在 Department
的实例上创建一个名为 library
的方法,它会为您调用适当的查询。
has_many
、has_one
或 has_and_belongs_to_many
关联也会发生同样的情况,希望相反的情况发生。
它不是寻找 Library.find_by(id: department.library_id)
,而是相反,Department.find_by(library_id: department.library_id)
。
所有这些都可以通过关联方法轻松访问。
department = Department.first
library = department.library
回到这个问题,就我个人而言,我喜欢将最大的数据集展示给我的观点,然后从那里缩小范围。
我只会向视图发送一个 @department
,而不会费心创建一个方法来显示名称或 delegate
从图书馆到部门(带前缀)的名称以获得 library_name
方法。
<% @departments.each do |department| %>
<tr>
<td><%= department.name %></td>
<td><%= department.description %></td>
<td><%= department.library.name %></td>
<td><%= link_to 'Show', department %></td>
<td><%= link_to 'Edit', edit_department_path(department) %></td>
<td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
问题二:
不幸的是,我没有多少答案。问题是可以使用的信息很少,而且现在我们涉及许多可能正在发送的方法,而 nil 可以多米诺骨牌一直到您的模型方法。
我强烈怀疑你们的一个部门没有 library_id
,这会导致循环崩溃,因为这取决于每个部门都有图书馆。
编辑
问题三:
要获得反向关系,只需执行 department.libraries
。
在您描述的情况下,您有一个部门集合,这与单个部门实例不同。
对 rails 有点陌生,并试图通过 Rails 文档或 rails 指南找到我一直遇到的问题的一些答案,但运气不佳,或者rails 教程。
我的目标是接受 rails 处理事情的方式,并尝试让其他开发人员以后更容易进入该项目。
问题 1:重构问题
Rails 重构实践。我不确定这是否应该放在模型或控制器中,我真的只是想知道哪些项目应该放在控制器中,哪些应该放在模型中。
第一次迭代:
<% @departments.each do |department| %>
<tr>
<td><%= department.name %></td>
<td><%= department.description %></td>
<td>
<%= library = Library.find_by(id: department.library_id).name %>
</td>
<td><%= link_to 'Show', department %></td>
<td><%= link_to 'Edit', edit_department_path(department) %></td>
<td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
这对我来说似乎是错误的,并且似乎应该将其作为后端逻辑从该部分中删除。
第二次迭代:
型号
class Department < ApplicationRecord
belongs_to :library
def get_library_name(lib_id)
library = Library.find_by(id: lib_id)
return library.name
end
end
查看
<% @departments.each do |department| %>
<tr>
<td><%= department.name %></td>
<td><%= department.description %></td>
<td>
<%= department.get_library_name(department.library_id) %>
</td>
<td><%= link_to 'Show', department %></td>
<td><%= link_to 'Edit', edit_department_path(department) %></td>
<td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
这感觉更正确,但并非完全正确,所以我不确定如何才能将其更改为更正确,特别是因为列出记录的索引视图非常相似。
我该如何重构它?
问题 2:我的测试不会通过
无论如何,我的测试没有通过。我猜这就是我使用一对多关系的方式。
test "should get index" do
get departments_url
assert_response :success
end
错误:
DepartmentsControllerTest#test_should_get_index:
ActionView::Template::Error: undefined method `name' for nil:NilClass
app/models/department.rb:6:in `get_library_name'
app/views/admin/departments/index.html.erb:21:in `block in _app_views_admin_departments_index_html_erb__1894713831414342893_57284960'
app/views/admin/departments/index.html.erb:16:in `_app_views_admin_departments_index_html_erb__1894713831414342893_57284960'
test/controllers/departments_controller_test.rb:11:in `block in <class:DepartmentsControllerTest>'
问题一:
您可以使用关联方法轻松访问关联图书馆的查询。
每当您将 belong_to :library
添加到 Department
时,您实际上只是在 Department
的实例上创建一个名为 library
的方法,它会为您调用适当的查询。
has_many
、has_one
或 has_and_belongs_to_many
关联也会发生同样的情况,希望相反的情况发生。
它不是寻找 Library.find_by(id: department.library_id)
,而是相反,Department.find_by(library_id: department.library_id)
。
所有这些都可以通过关联方法轻松访问。
department = Department.first
library = department.library
回到这个问题,就我个人而言,我喜欢将最大的数据集展示给我的观点,然后从那里缩小范围。
我只会向视图发送一个 @department
,而不会费心创建一个方法来显示名称或 delegate
从图书馆到部门(带前缀)的名称以获得 library_name
方法。
<% @departments.each do |department| %>
<tr>
<td><%= department.name %></td>
<td><%= department.description %></td>
<td><%= department.library.name %></td>
<td><%= link_to 'Show', department %></td>
<td><%= link_to 'Edit', edit_department_path(department) %></td>
<td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
问题二:
不幸的是,我没有多少答案。问题是可以使用的信息很少,而且现在我们涉及许多可能正在发送的方法,而 nil 可以多米诺骨牌一直到您的模型方法。
我强烈怀疑你们的一个部门没有 library_id
,这会导致循环崩溃,因为这取决于每个部门都有图书馆。
编辑
问题三:
要获得反向关系,只需执行 department.libraries
。
在您描述的情况下,您有一个部门集合,这与单个部门实例不同。