Ruby Rails 4 个带 Active Record 的嵌套表单
Ruby on Rails 4 Nested Forms with Active Record
我是 Rails 的新手,刚刚构建我的第一个应用程序(来自 PHP 和 .NET 背景并且喜欢它顺便说一句)但是我 运行 遇到了一个问题我正在努力寻找答案,尽管我确信有一个简单的答案!
我的项目有3个主要模型;位置、服务和定位服务
有多种服务可用,一个位置可以有任意数量的服务。基本上我在位置服务中使用记录来存储所选服务的 ID 和位置的 ID。
我的模型简化版如下:
class Location < ActiveRecord::Base
has_many :location_services
end
class Service < ActiveRecord::Base
has_many :location_services
end
class LocationService < ActiveRecord::Base
belongs_to :location
belongs_to :service
end
我已经阅读了有关嵌套表单的内容,并使用 'accepts_nested_attributes_for' 允许子表单编辑从另一个模型中获取的数据,这听起来与我想要的非常相似,只是我不想只能够编辑我拥有的位置服务,我希望能够从每个可用服务中选择复选框,然后在选中并保存我的位置时,我希望它为位置服务中的每个选定服务创建一条记录 table 使用位置的 ID 和服务的 ID
我确定我可以使用 Services.all 轻松生成所有复选框,然后循环遍历它,然后在我的控制器中从 POST 中获取所有勾选的复选框,循环遍历它们并构建一个所有这些的数组,然后将该数组传递给 Location.location_services.create([]) 但这是 rails 我觉得可能有更好的方法吗?
所以首先,我是不是在用一种愚蠢的方式来做这件事?有没有更好的方法而不是 3 tables?是否有生成和保存所有服务的好方法?
非常感谢
大卫
has_many
关系为您的模型添加了许多方法。从中您只需要 collection_singular_ids
方法,它执行以下操作:
Replace the collection with the objects identified by the primary keys
in ids. This method loads the models and calls collection=
.
以上方法可与collection_check_boxes
as explained in this tutorial结合使用。所以在你的情况下你会有这样的东西:
f.collection_check_boxes :location_service_ids, LocationService.all, :id, :name
请注意,最后一个参数(此处为 :name
)是 text_method_option
,它会为您的复选框生成标签。
最后但同样重要的是:不要忘记正确使用accepts_nested_attributes
。
非常感谢 Yan 在这方面的帮助,我终于设法解决了我的问题,而且事实证明它非常简单。我在这里发帖,希望对其他人有所帮助。
我需要做的是通过位置服务添加与服务的 has_many 关系,因此我的模型现在如下所示:
class Location < ActiveRecord::Base
has_many :services, :through => :location_services
has_many :location_services
accepts_nested_attributes_for :location_services
end
我更新了我的观点以包括:
<%= f.collection_check_boxes(:service_ids, Service.all, :id, :name) do |b| %>
<%= b.label(class: "check_box") do %>
<%= b.check_box %>
<%= b.object.name %>
<% end %>
<% end %>
然后在我的控制器中我有:
def location_params
params.require(:location).permit(:service_ids => [])
end
为简单起见,我删除了所有其他字段。然后最后在Update方法中,就这么简单:
def update
@location.update(location_params)
redirect_to @location, notice: 'Location was successfully updated.'
end
希望这对某人有所帮助!!
非常感谢
大卫
我是 Rails 的新手,刚刚构建我的第一个应用程序(来自 PHP 和 .NET 背景并且喜欢它顺便说一句)但是我 运行 遇到了一个问题我正在努力寻找答案,尽管我确信有一个简单的答案!
我的项目有3个主要模型;位置、服务和定位服务
有多种服务可用,一个位置可以有任意数量的服务。基本上我在位置服务中使用记录来存储所选服务的 ID 和位置的 ID。
我的模型简化版如下:
class Location < ActiveRecord::Base
has_many :location_services
end
class Service < ActiveRecord::Base
has_many :location_services
end
class LocationService < ActiveRecord::Base
belongs_to :location
belongs_to :service
end
我已经阅读了有关嵌套表单的内容,并使用 'accepts_nested_attributes_for' 允许子表单编辑从另一个模型中获取的数据,这听起来与我想要的非常相似,只是我不想只能够编辑我拥有的位置服务,我希望能够从每个可用服务中选择复选框,然后在选中并保存我的位置时,我希望它为位置服务中的每个选定服务创建一条记录 table 使用位置的 ID 和服务的 ID
我确定我可以使用 Services.all 轻松生成所有复选框,然后循环遍历它,然后在我的控制器中从 POST 中获取所有勾选的复选框,循环遍历它们并构建一个所有这些的数组,然后将该数组传递给 Location.location_services.create([]) 但这是 rails 我觉得可能有更好的方法吗?
所以首先,我是不是在用一种愚蠢的方式来做这件事?有没有更好的方法而不是 3 tables?是否有生成和保存所有服务的好方法?
非常感谢 大卫
has_many
关系为您的模型添加了许多方法。从中您只需要 collection_singular_ids
方法,它执行以下操作:
Replace the collection with the objects identified by the primary keys in ids. This method loads the models and calls
collection=
.
以上方法可与collection_check_boxes
as explained in this tutorial结合使用。所以在你的情况下你会有这样的东西:
f.collection_check_boxes :location_service_ids, LocationService.all, :id, :name
请注意,最后一个参数(此处为 :name
)是 text_method_option
,它会为您的复选框生成标签。
最后但同样重要的是:不要忘记正确使用accepts_nested_attributes
。
非常感谢 Yan 在这方面的帮助,我终于设法解决了我的问题,而且事实证明它非常简单。我在这里发帖,希望对其他人有所帮助。
我需要做的是通过位置服务添加与服务的 has_many 关系,因此我的模型现在如下所示:
class Location < ActiveRecord::Base
has_many :services, :through => :location_services
has_many :location_services
accepts_nested_attributes_for :location_services
end
我更新了我的观点以包括:
<%= f.collection_check_boxes(:service_ids, Service.all, :id, :name) do |b| %>
<%= b.label(class: "check_box") do %>
<%= b.check_box %>
<%= b.object.name %>
<% end %>
<% end %>
然后在我的控制器中我有:
def location_params
params.require(:location).permit(:service_ids => [])
end
为简单起见,我删除了所有其他字段。然后最后在Update方法中,就这么简单:
def update
@location.update(location_params)
redirect_to @location, notice: 'Location was successfully updated.'
end
希望这对某人有所帮助!!
非常感谢 大卫