I've got a polymorphic association for group_invitations
. You can invite users to join product
as a member or to join product_customer
(it's not user, it's something like product customer case) as a customer. To be able to join they have to accept the invitation.
Since it's polymorphic I decided to do the create action with more controllers instead of using hidden fields. Thanks to that route actions look like:
products/1/group_invitations
product_customers/1/group_invitations
My problem is that I render all the forms on the product show page. So it's easy to render the form for the certain product like:
<%= form_for([@product, GroupInvitation.new]) do %>
..........
But I'm stuck with the product_customer. Since product has_many product_customers
(again it's not the user but the "product customer case"), user should choose the product_customer
instance with collection select and rails should set the form action route based on that. How can I achieve that? Is there a rails way to set it somehow or I gotta use 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 Rest of the code is provided just to show how controllers/routes look like. According to me not necessary to solve the problem.
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
products/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
controllers/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
.........
I ended up using this:
There is always a value selected in the collection select. On loading the page it's set to the first item. So if the user doesn't change it then it will be saved with that.
<%= form_for([@product_customers.first, GroupInvitation.new]) do |f| %>
If the user starts playing with the collection select then it changes the route with 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);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.