Rails 7 帮助干燥图像附件?
Rails 7 help DRYing out image attachments?
请耐心等待,我是发帖的新手,Rails 如果我措辞不当,非常抱歉!
我正在开发一个具有许多相似模型的 Rails 应用程序。每个视图都有一个 _form.html.haml
部分,内容不同但包含类似的组件,例如提交、删除等按钮。每个模型 has_many_attached 张照片,并且在表单中可以添加或删除照片。用于删除照片的 haml 看起来像这样,其中变量被替换为 _form.html.haml
中的任何视图:
.gallery#form
- @VARIABLE.photo.each_with_index do |image, index|
.overlay-container
.img-square{ :style => "background-image: url(#{rails_blob_url(photo(@VARIABLE, index))})", :alt => "Photo of #{image}" }
= link_to("Delete", delete_image_attachment_VARIABLE_url(image), method: :delete, class: 'button delete overlay')
要对每张照片进行删除,每个控制器中都有以下代码:
def delete_image_attachment
@photo = ActiveStorage::Attachment.find(params[:id])
@photo.purge
redirect_back fallback_location: @VARIABLE
flash[:success] = 'Photo was successfully deleted.'
end
并且 routes.rb
每个模型都有这段代码:
resources :VARIABLE do
member do
delete :delete_image_attachment
end
end
但是,我需要在大约十几个模型上执行此操作。我的目标是将画廊带入新的部分,因为无论其他内容如何,它都会在每个 _form 中使用。但是,删除功能(尽管每个控制器都相同)与每个模型的 controller/routes.rb 绑定。
一定有某种方法可以将此功能干燥到几个文件中,而不是为每个模型复制粘贴,但我的 Google 搜索没有找到任何结果。因此,非常感谢任何指导或更好的 Rails 约定!
如果我对结构的理解正确,听起来你会想要做如下的事情:
创建一个 top-level 控制器来处理删除图像
- 这可以被任何页面使用。
- 这需要以下查询参数:
id
要删除的照片 ID。
redirect
操作完成后将用户重定向到哪里。
路线
现在只有 1 个路由来处理上面的控制器。
创建可重复使用的部分
用于使用重定向 url 渲染图像集合,允许您为部分设置以下状态:
photos
要渲染的图像集合。
redirect_url
这作为查询参数传递给集中删除图像控制器。
想法和模拟示例
这应该能够让您的实现变干。目前我看到的唯一将视图与删除结合在一起的是重定向 URL。通过将其抽象出来并将其本质上移动到部分参数将允许 re-use 和灵活性。
您已经通过 @VARIABLE
确定了您的耦合,这里是我期望它最终看起来如何的快速模拟:
部分模板
.gallery#form
- @photos.each_with_index do |image, index|
.overlay-container
.img-square{ :style => "background-image: url(#{rails_blob_url(photo(@VARIABLE, index))})", :alt => "Photo of #{image}" }
= link_to("Delete", delete_image_attachment_url(image, redirect: @redirect_url), method: :delete, class: 'button delete overlay')
需要:photos
和 redirect_url
因此,请确保在消费控制器上设置 @photos
和 @redirect_url
。
要在模板中访问实例属性的示例
@photos = GET_PHOTOS_HERE
@redirect_url = 'some-redirect-path'
render partial: 'photos_partial'
带有模板局部参数的示例
photos = GET_PHOTOS_HERE
render partial: 'photos_partial', locals: { photos: photos, redirect: 'some-redirect-path' }`
注意:您可能需要更改访问模板中局部变量的方式。
https://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables
控制器
def delete_image_attachment
@photo = ActiveStorage::Attachment.find(params[:id])
@photo.purge
redirect_back fallback_location: params[:redirect]
flash[:success] = 'Photo was successfully deleted.'
end
路线
这里只有删除任何图片附件的单一路径,指向上面的单一控制器。
delete 'resources/image_attachment/:id', to: 'resources#delete_image_attachment'
注意:将“资源”替换为您的控制器名称或您想要的scoping/naming。
PS:我已经有一段时间没做过了Rails所以我不能完全确定准确性或你的环境。
请耐心等待,我是发帖的新手,Rails 如果我措辞不当,非常抱歉!
我正在开发一个具有许多相似模型的 Rails 应用程序。每个视图都有一个 _form.html.haml
部分,内容不同但包含类似的组件,例如提交、删除等按钮。每个模型 has_many_attached 张照片,并且在表单中可以添加或删除照片。用于删除照片的 haml 看起来像这样,其中变量被替换为 _form.html.haml
中的任何视图:
.gallery#form
- @VARIABLE.photo.each_with_index do |image, index|
.overlay-container
.img-square{ :style => "background-image: url(#{rails_blob_url(photo(@VARIABLE, index))})", :alt => "Photo of #{image}" }
= link_to("Delete", delete_image_attachment_VARIABLE_url(image), method: :delete, class: 'button delete overlay')
要对每张照片进行删除,每个控制器中都有以下代码:
def delete_image_attachment
@photo = ActiveStorage::Attachment.find(params[:id])
@photo.purge
redirect_back fallback_location: @VARIABLE
flash[:success] = 'Photo was successfully deleted.'
end
并且 routes.rb
每个模型都有这段代码:
resources :VARIABLE do
member do
delete :delete_image_attachment
end
end
但是,我需要在大约十几个模型上执行此操作。我的目标是将画廊带入新的部分,因为无论其他内容如何,它都会在每个 _form 中使用。但是,删除功能(尽管每个控制器都相同)与每个模型的 controller/routes.rb 绑定。
一定有某种方法可以将此功能干燥到几个文件中,而不是为每个模型复制粘贴,但我的 Google 搜索没有找到任何结果。因此,非常感谢任何指导或更好的 Rails 约定!
如果我对结构的理解正确,听起来你会想要做如下的事情:
创建一个 top-level 控制器来处理删除图像
- 这可以被任何页面使用。
- 这需要以下查询参数:
id
要删除的照片 ID。redirect
操作完成后将用户重定向到哪里。
路线
现在只有 1 个路由来处理上面的控制器。
创建可重复使用的部分
用于使用重定向 url 渲染图像集合,允许您为部分设置以下状态:
photos
要渲染的图像集合。redirect_url
这作为查询参数传递给集中删除图像控制器。
想法和模拟示例
这应该能够让您的实现变干。目前我看到的唯一将视图与删除结合在一起的是重定向 URL。通过将其抽象出来并将其本质上移动到部分参数将允许 re-use 和灵活性。
您已经通过 @VARIABLE
确定了您的耦合,这里是我期望它最终看起来如何的快速模拟:
部分模板
.gallery#form
- @photos.each_with_index do |image, index|
.overlay-container
.img-square{ :style => "background-image: url(#{rails_blob_url(photo(@VARIABLE, index))})", :alt => "Photo of #{image}" }
= link_to("Delete", delete_image_attachment_url(image, redirect: @redirect_url), method: :delete, class: 'button delete overlay')
需要:photos
和 redirect_url
因此,请确保在消费控制器上设置 @photos
和 @redirect_url
。
要在模板中访问实例属性的示例
@photos = GET_PHOTOS_HERE
@redirect_url = 'some-redirect-path'
render partial: 'photos_partial'
带有模板局部参数的示例
photos = GET_PHOTOS_HERE
render partial: 'photos_partial', locals: { photos: photos, redirect: 'some-redirect-path' }`
注意:您可能需要更改访问模板中局部变量的方式。
https://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables
控制器
def delete_image_attachment
@photo = ActiveStorage::Attachment.find(params[:id])
@photo.purge
redirect_back fallback_location: params[:redirect]
flash[:success] = 'Photo was successfully deleted.'
end
路线
这里只有删除任何图片附件的单一路径,指向上面的单一控制器。
delete 'resources/image_attachment/:id', to: 'resources#delete_image_attachment'
注意:将“资源”替换为您的控制器名称或您想要的scoping/naming。
PS:我已经有一段时间没做过了Rails所以我不能完全确定准确性或你的环境。