Is there a way to change the form structure of the form without affecting its functionality?

0

I'm handling the error messages using the gem toastr and a function in javascript that works with the gem.

One of the parameters is resource and in the partial form _comments it does not have it, and is defined as follows:

<%= form_for [*commentable, Comment.new], local: true do |f|  %>
  <%= render 'shared/devisemes' %> //Esto genera error
  <div class="form-group">
    <%= f.text_area :body, autofocus: true, :rows => 2, style: 'width:100%;', placeholder: "Add a comment", class: "form-control" %><br/>
  </div>
  <%= f.submit "Commentate", class: "btn btn-primary pull-right"  %>
<% end %>

Logically, how the function uses resources generates an error because it does not recognize resource :

**undefined local variable or method 'resource' for**

Is there a way to redefine the following line:

 <%= form_for [*commentable, Comment.new], local: true do |f|  %>

in this way to make it work?

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>

This is the code that is invoked in views:

_devisemes.html.erb

<% unless resource.errors.empty? %>
  <script type="text/javascript">
    <% resource.errors.full_messages.each do |value| %>
      toastr.error('<%= value %>')
    <% end %>
  </script>
<% end %>

<% unless resource.errors.empty? %>
  <script type="text/javascript">
    <% resource.errors.full_messages.each do |value| %>
      toastr.error('<%= value %>')
    <% end %>
  </script>
<% end %>

Example of invocation from a form:

<div class="row">
  <div class="col-md-4 col-md-offset-4">

    <h2 class="text-center">Sign up</h2>
    <br/>

    <%= form_for(resource, as: resource_name, url:     registration_path(resource_name)) do |f| %>
  <%= render 'shared/devisemes' %> //Acá se invoca

      <div class="form-group">
        <%= f.text_field :fullname, autofocus: true, placeholder: "Full Name", class: "form-control" %>
     </div>

  <div class="form-group">
    <%= f.email_field :email, autofocus: true, placeholder: "Email", class: "form-control" %>
  </div>

  <div class="form-group">
    <%= f.password_field :password, autocomplete: "off",  placeholder: "Password", class: "form-control" %>
  </div>

  <div class="actions">
    <%= f.submit "Sign up", class: "btn btn-primary" %>
  </div>
<% end %>

    
asked by García Henry 02.11.2017 в 02:39
source

1 answer

0

The problem is that resource is a helper of Devise which is used to recognize the user (ie user ), however once passed the process of sign up , this helper is no longer available.

Instead of forcing resource as a parameter, you could try the object in question, for example, @question ; for this you will need to use local variables in your partial, something similar to this:

<%= render 'shared/devisemes', resource: commentable.last %>

That way, resource will have the object commentable (which can be question or answer ) and will look for the errors of that object (instead of those of user ). You can adapt this (using the appropriate variable) for all the cases you need.

One option (not very elegant) that could serve you, is to pass the message of the first error with @comment.errors.full_messages.first to flash and this way you would be able to show the message coming from the validation to the user, for example (in CommentsController#create ) :

redirect_to question_path(commentable), flash: { alert: @comment.errors.full_messages.first }

With this line you would no longer need the partial _devisemes.html.erb in the form:

<%= form_for [*commentable, Comment.new], local: true do |f|  %>
  <div class="form-group">
    <%= f.text_area :body, autofocus: true, :rows => 2, style: 'width:100%;', placeholder: "Add a comment", class: "form-control" %><br/>
  </div>

  <%= f.submit "Commentate", class: "btn btn-primary pull-right"  %>
<% end %>

The only disadvantage would be that, in case more than one error was generated in the validation, you would only see the first error.

    
answered by 02.11.2017 в 03:29