I'm trying to render a simple form to create and edit a campaign
resource. Normally, in a rails application, I would render the form like so:
<%= simple_form_for @campaign do |f| %>
....inputs.....
<% end %>
Normally, this would be enough to perform both a new and edit action for the campaign
. However in this scenario, I can't use the same approach because the urls for new and edit cannot be inferred. They are two different urls. Here is my code:
New Action
.max-w-4xl.mx-auto
.mt-5.bg-white.shadow.sm:rounded-lg
.px-4.py-5.sm:p-6
%h3.text-lg.leading-6.font-medium.text-gray-900
New Campaign
.mt-5
= render 'form'
Edit Action
.max-w-4xl.mx-auto
.mt-5.bg-white.shadow.sm:rounded-lg
.px-4.py-5.sm:p-6
%h3.text-lg.leading-6.font-medium.text-gray-900
Editing Campaign: "#{@campaign.name}"
.mt-5
= render 'form'
For the new action, I have simple form coded like so:
= simple_form_for(@campaign, as: :campaign, method: :post, url: partner_campaigns_path(@partner)) do |f|
For the edit action I have simple form like this:
= simple_form_for(@campaign, as: :campaign, method: :patch, url: campaign_path(@campaign)) do |f|
I want to keep my _form.html.haml
but I can't seem to pass the distinct urls into it. I've tried to pass the url and action as local variables for rendering a partial but they seem to always be blank. Example below:
= render 'form', locals: { url: campaign_path(@campaign), http_action: :patch }
Everytime I do a variation of this approach, I can't get the url
or http_action
variable. Am I doing something incorrect?
CodePudding user response:
You can use #new_record?
or #persisted?
methods to achieve this
- http_method = @campaign.new_record? ? :post : :patch
- url = @campaign.new_record? ? partner_campaigns_path(@partner) : campaign_path(@campaign)
= simple_form_for(@campaign, as: :campaign, method: http_method, url: url) do |f|
Or you can incapsulate this logic in a helper method
module ApplicationHelper
def resolve_form_options(campaign, partner)
if campaign.new_record?
{ url: partner_campaigns_path(partner), method: :post }
else
{ url: campaign_path(campaign), method: :patch }
end
end
end
= simple_form_for(@campaign, as: :campaign, **resolve_form_options(@campaign, @partner)) do |f|
CodePudding user response:
You can pass a variable from the new and edit pages from where the form partial is being rendered. Something like - <%= render 'form', request_method: 'new' %>
if passing from the new view. And then inside the form partial, you can do -
= simple_form_for(@campaign, as: :campaign, method: request_method == 'new' ? :post : :patch, URL: (request_method == 'new' ? partner_campaigns_path(@partner) : campaign_path(@campaign) )) do |f|
.
I think this might not be the correct way to do so and might be better ways to do. But if it works, then hey please mark the answer as correct. :)