我有group_invitations
的多态关联。您可以邀请用户加入product
作为会员,或加入product_customer
(不是用户,就像产品客户案例一样)作为客户。为了能够加入,他们必须接受邀请。
由于它是多态的,我决定使用更多控制器而不是使用隐藏字段来创建动作。感谢路线行为如下:
products/1/group_invitations
product_customers/1/group_invitations
我的问题是我在产品展示页面上呈现所有表单。因此,为特定产品呈现表单很容易,例如:
<%= form_for([@product, GroupInvitation.new]) do %>
..........
但我坚持使用product_customer。由于product has_many product_customers
(同样不是用户而是“产品客户案例”),用户应该选择带有集合选择的product_customer
实例,并且rails应该基于此设置表单操作路由。我怎样才能做到这一点?是否有某种方式来设置它或我必须使用js / jquery?
<%= form_for( #should be set based on collection select ) do %>
<%= f.collection_select(:product_customer_id, @product.product_customers, :id, :name) %>
TL; DR其余代码仅用于显示控制器/路由的外观。根据我没有必要解决问题。
的routes.rb
resources :group_invitations, only: :destroy do
member do
patch :accept
end
end
resources :products do
resources :group_invitations, only: [:new, :create], module: :products
end
resources :product_customers do
resources :group_invitations, only: [:new, :create], module: :product_customers
end
产品/ group_invitations_controller
class Products::GroupInvitationsController < GroupInvitationsController
before_action :set_group_invitable
private
def set_group_invitable
@group_invitable = Product.find(params[:product_id])
end
end
product_customers / group_invitations_controller
class ProductCustomers::GroupInvitationsController < GroupInvitationsController
before_action :set_group_invitable
private
def set_group_invitable
@group_invitable = ProductCustomer.find(params[:product_customer_id])
end
end
控制器/ group_invitations_controller.rb
def create
@product = Product.find(params[:product_id])
@group_invitation = @group_invitable.group_invitations.new(group_invitations_params)
@group_invitation.sender = @product.owner
@group_invitation.recipient = @recipient
if @group_invitation.save
.........
答案 0 :(得分:0)
我最终使用了这个:
在集合选择中始终选择一个值。在加载页面时,它被设置为第一个项目。因此,如果用户没有更改它,那么它将被保存。
<%= form_for([@product_customers.first, GroupInvitation.new]) do |f| %>
如果用户开始使用集合选择,那么它会使用jquery更改路径。
$(document).on('change', '#product-customer-collection-select', function () {
var newRouteId = $(this).val();
var newActionURL = "/product_customers/" + newRouteId + "/group_invitations";
$(this).closest("form").attr("action", newActionURL);
});