So, i have 2 forms. In one of them, im submitting the form to the method "create", the default one created with resources:
resources :correlation_engine_rules
In this form, i just link the form with the path via simple_form:
<%= simple_form_for(:correlation_engine_rule, url: correlation_engine_rules_path, :html => { :remote => true, :method => :post }) do |f| %>
Now, if i submit, im calling the method called "create" in my controller:
def create
...things happening...
respond_to do |format|
if @rule.save
format.html { redirect_to correlation_engine_rules_path(value: @cep_status), notice: "#{I18n.t('controllers.rule_created')}" }
format.js { flash[:notice] = "#{I18n.t('controllers.rule_created')}" }
format.json { head :no_content }
else
format.html do
redirect_to correlation_engine_rules_path(@rule),
alert: @rule.errors.full_messages.map { |msg| "<li>#{msg}</li>" }.join
end
format.js
format.json { render json: @rule.errors, status: :unprocessable_entity }
end
end
end
The rule is saved and the page is redirect to that path. This is working. Now, i wanted to have a new form, with another method controller to process these new fields.
So, i created new routes:
resources :correlation_engine_rules do
get :basic_rule_2, on: :collection
post :create_basic_rule_2, on: :collection
end
And then i associated the new form with my new method controller (create_basic_rule_2):
<%= simple_form_for(:correlation_engine_rule, url: create_basic_rule_2_correlation_engine_rules_path, :html => { :remote => true, :method => :post }) do |f| %>
When i submit, the controller is called correctly, the problem comes when doing the exact same redirect as before. Here the redirect fails and it tried to render a view called "create_basic_rule_2", which i don't understand. I'm telling him to redirect to correlation_engine_rules_path as before.
def create_basic_rule_2
...things happening...
respond_to do |format|
if @rule.save
format.html { redirect_to correlation_engine_rules_path(value: @cep_status), notice: "#{I18n.t('controllers.rule_created')}" }
format.js { flash[:notice] = "#{I18n.t('controllers.rule_created')}" }
format.json { head :no_content }
else
Rails.logger.error "\n\n\n\ NO GUARDADO"
format.html do
redirect_to correlation_engine_rules_path(@rule),
alert: @rule.errors.full_messages.map { |msg| "<li>#{msg}</li>" }.join
end
end
end
end
What bugges me is that is the exact same code, and the path is the same wherever you are, so why create is not render a view called "create", but my method create_basic_rule_2 is trying to render a view called "create_basic_rule_2?
Here is the error that i get:
<ActionView::MissingTemplate: Missing template correlation_engine_rules/create_basic_rule_2, application/create_basic_rule_2 with {:locale=>[:es, :en], :formats=>[:js, :html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder]}. Searched in:
* "/opt/rb/var/www/rb-rails/lib/modules/vault/app/views"
* "/opt/rb/var/www/rb-rails/lib/modules/social/app/views"
* "/opt/rb/var/www/rb-rails/lib/modules/monitor/app/views"
* "/opt/rb/var/www/rb-rails/lib/modules/location/app/views"
* "/opt/rb/var/www/rb-rails/lib/modules/ips/app/views"
* "/opt/rb/var/www/rb-rails/lib/modules/flow/app/views"
* "/opt/rb/var/www/rb-rails/lib/modules/correlation_engine_rule/app/views"
* "/opt/rb/var/www/rb-rails/app/views"
* "/usr/local/rvm/gems/ruby-2.1.2/gems/devise-3.5.10/app/views"
>
If you setup a MRE and check the request type (hint its on the first line of the logs) of the request you can see that the issue is actually pretty straight forward:
<%= simple_form_for(:correlation_engine_rule, url: create_basic_rule_2_correlation_engine_rules_path, :html => { :remote => true, :method => :post }) do |f| %>
Rails UJS defaults to sending those pesky application/javascript
AJAX requests when you set the data-remote="true"
option.
Which means that the controller is actually executing this block:
format.js { flash[:notice] = "#{I18n.t('controllers.rule_created')}" }
Since it does not render or redirect rails will implicitly try to find a template named create_basic_rule_2
. Redirecting in format.js
response won't actually do anything since its an AJAX request.
Instead you want to set remote: false
:
<%= simple_form_for(:correlation_engine_rule, url: create_basic_rule_2_correlation_engine_rules_path, html: { remote: false, method: :post }) do |f| %>
Which will just submit the form normally and trigger the format.html
block.
If you really wanted to send an ajax request and cause a redirect you would have to create a template and set window.location
:
# views/controller_name/correlation_engine_rule.js.erb
window.location = '/new_location'