submitting form using remote: true in rails not working - ruby-on-rails-3

This is my view
<%= form_tag url_for(action: :comt, id: #com.id), remote: true do |f| %>
<textarea name="inst">test</textarea>
<button class="small" id="btn">Submit</button>
Here is my controller:
def comt
id= params[:id]
#com = comment.find id
if #com.update_attribute(:instruction, params[:inst])
redirect_to action: :index
end
end
It is working correctly but i need it using ajax.
If i remove redirect_to it throwing error message. Where i am wrong. Can anyone correct it.

Related

The error message when trying to login from devise is not showing in a Rails 7.0 application

I have a rails 7.0 application, in my application.html.erb
<body>
<%= yield %>
<div class="signin-container">
<div class="signin-container-inner">
<%- flash.each do |name, msg| -%>
<%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
<%- end -%>
</div>
</div>
</body>
When I visit signin page and add some wrong email or password the error message is not showing.
Since Ruby on Rails 7 uses :turbo_stream, we need to make some modifications to get what you need.
First, we let's add a new parent controller for Devise:
# frozen_string_literal: true
# app/controllers/turbo_devise_controller.rb
class TurboDeviseController < ApplicationController
class Responder < ActionController::Responder
def to_turbo_stream
controller.render(options.merge(formats: :html))
rescue ActionView::MissingTemplate => e
if get?
raise e
elsif has_errors? && default_action
render rendering_options.merge(formats: :html, status: :unprocessable_entity)
else
redirect_to navigation_location
end
end
end
self.responder = Responder
respond_to :html, :turbo_stream
end
Second, we also need to tell Devise to use our new controller and also add a class to handle our errors:
# frozen_string_literal: true
# app/config/initializers/devise.rb
# ! Create custom failure for turbo
class TurboFailureApp < Devise::FailureApp
def respond
if request_format == :turbo_stream
redirect
else
super
end
end
def skip_format?
%w(html turbo_stream */*).include? request_format.to_s
end
end
Devise.setup do |config|
...
config.parent_controller = 'TurboDeviseController'
config.navigational_formats = ['*/*', :html, :turbo_stream]
config.warden do |manager|
manager.failure_app = TurboFailureApp
end
...
end
That's it.
More information about it: GoRails - How to use Devise with Hotwire & Turbo.js
Here is a workaround this issue that occurs when using Rails 7, Hotwire, Turbo, and Devise together. By passing data:{turbo: false} along with each Devise form, it can prevent Turbo from conflicting with the Devise authentication process. This should allow Devise to function properly while still using Hotwire and Turbo in your Rails application.
Here is an example of how you might use data:{turbo: false} on a Devise form:
<%= form_for(resource, as: resource_name, url: session_path(resource_name), data: {turbo: false}) do |f| %>
<%= f.label :email %>
<%= f.email_field :email, autofocus: true %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Log in" %>
<% end %>
In this example, the data: {turbo: false} is being passed as an option to the form_for helper method. This tells Turbo to not apply any of its features to this form, which should prevent any conflicts with Devise's authentication process.

Show validation errors in view for custom Devise login form

At the moment, I'm building a Rails platform using Spree Commerce where I need two Devise login forms.
The default Devise login forms are already implemented. For the second (custom) Devise form, I created the following view:
global_login.html.erb
<div class="inner">
<h2 class="large-margin">
Login
</h2>
<%= form_for(Spree::User.new, :url => spree_login_path) do |f| %>
<%= f.error_messages %>
<%= f.email_field :email, {:value => params[:email], :placeholder => 'Email address', :class => 'input'} %>
<%= f.password_field :password, {:placeholder => 'Password', :class => 'input'} %>
<%= f.submit 'Login', :class => 'submit' %>
<% end %>
</div>
This view does display a Devise login form. However, every time I submit the form, I'm being redirected to the default Devise view where the validation errors are shown.
Does somebody know a solution to this problem?
Cheers!
I found a workaround for this issue. I added a param to one of the forms named "inside_cart". When the request is send to the #create method, I check if the param is present.
I overwrote the Spree::UserSessionsController#create method as follows:
Spree::UserSessionsController.class_eval do
layout false
def create
authenticate_spree_user!
if spree_user_signed_in?
respond_to do |format|
format.html {
flash[:success] = Spree.t(:logged_in_succesfully)
redirect_back_or_default(after_sign_in_path_for(spree_current_user))
}
format.js {
user = resource.record
render :json => {:ship_address => user.ship_address, :bill_address => user.bill_address}.to_json
}
end
else
if params[:spree_user] && params[:spree_user][:inside_cart]
flash.now[:error] = t('devise.failure.invalid')
render :new, layout: false
else
flash.now[:error] = t('devise.failure.invalid')
render 'spree/users/global_login', layout: 'spree/layouts/spree_application'
end
end
end
end

Recaptcha only showing up after page refresh - Rails 4 - Devise

I have installed recaptcha according to the gem instructions, however when I view the sign_up page (using Devise), the catcha doesn't appear until I refresh the page.
Looking through other comments, the recommendation is to disable turbolinks (which I am using) by changing the sign_in link to:
<%= link_to "Sign up", new_registration_path, "data-no-turbolink" => true %><br />
I have tried this, but I still don't get the captcha until I do a page refresh.
Relevant code:
Views/devise/registrations/new.html.erb
................
<%= recaptcha_tags %>
................
/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def create
if !verify_recaptcha
flash.delete :recaptcha_error
build_resource
resource.valid?
resource.errors.add(:base, "There was an error with the recaptcha code below. Please re-enter the code.")
clean_up_passwords(resource)
respond_with_navigational(resource) { render_with_scope :new }
else
flash.delete :recaptcha_error
super
end
end
def clean_up_passwords(*args)
# Delete or comment out this method to prevent the password fields from
# repopulating after a failed registration
end
end
Issue was that I needed to still include "class:" in the link:
<%= link_to "Sign up", new_user_registration_path, "data-no-turbolink" => true, class: "btn btn-primary btn-med" %>
Just try in controller this code
def create
if resource.valid? && !verify_recaptcha
clean_up_passwords(resource)
flash.delete :recaptcha_error
elsif !resource.valid? && verify_recaptcha
clean_up_passwords resource
respond_with resource
elsif !resource.valid? && !verify_recaptcha
flash.now[:alert] = "Recaptcha error"
flash.delete :recaptcha_error
clean_up_passwords resource
respond_with resource
end
end
And in your Views/devise/registrations/new.html.erb
<%= recaptcha_tags display: {theme: 'red', tabindex: 5}, ssl: false, noscript: false %>

Simple_Form and Bootstrap 3 Form Validation Notification Stopped Working

I'm still learning RoR and have followed various tutorials online. In that process I believe I have messed up the nice flash notifications that Bootstrap 2 showed when validating Simple_Form submissions. I have tried to update my code, but without success. Here is what I have so far...
Running:
Rails 3.2.13
Ruby 2.0.0
I just upgraded to Bootstrap 3 using this gem in my gemfile:
gem 'bootstrap-sass-rails'
In my application.html.erb I have:
<%= render 'layouts/messages' %>
In my _messages partial I have:
<% flash.each do |type, message| %>
<div class="alert <%= bootstrap_class_for(type) %> fade in">
<button class="close" data-dismiss="alert">×</button>
<%= message %>
</div>
<% end %>
In my application_helper.rb I have:
def bootstrap_class_for flash_type
case flash_type
when :success
"alert-success"
when :error
"alert-error"
when :alert
"alert-block"
when :notice
"alert-info"
else
flash_type.to_s
end
end
In my users_controller.rb I have:
def update
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'Account successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
And in my edit.html.erb view I have:
<%= simple_form_for(#user) do |f| %>
<%= f.input :firstname %>
<%= f.input :lastname %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= f.submit "Save changes", class: "btn btn-lg btn-primary" %>
<% end %>
The validation works, but when returned to the edit view, no formatting (red for errors) or flash message appears. Only a very hard to spot message outside each field is displayed. I must be missing some link between Simple_Form and Bootstrap 3, just don't know what.
I found another post where poster suggested to add:
config.input_class = "form-control"
to my simple_form initializer, but that gave me an error (think I might not have the latest version?):
undefined method `input_class=' for SimpleForm:Module (NoMethodError)
I wish I knew what was going on but I really hope someone can help me get the formatting and flash messages back. Apologies if this is a total newbie question, but I feel a little lost and possibly regretting that I upgraded too soon to Bootstrap 3 maybe.
A thousand thanks in advance to anyone reading all this :)
I got the following mix of code from railscasts.com and other websites.
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name == :notice ? "success" : "error" %>">
<a class="close" data-dismiss="alert">×</a>
<%= msg %>
</div>
<% end %>
Add this to the top of your controller:
respond_to :html, :json
Put this in each controller action:
def create
...
flash[:notice] = 'User was successfully created.'
respond_with(#user)
end
works with rails 3.2+ and 4.0 and twitter bootstrap rails 2, untested in tbsr 3 but will probably work fine.
This worked for me far much better than others as it;s shorter and includes all alert cases -> error, success, alert & notice provided by Bootstrap.
N.B: I renamed your _messages partial to _flash_messages because that is what most people use.
And for those who may be wondering where to generate the _flash_messages partial, it's pretty easy, just right-click your layouts folder in views and 'add new file'. You can call it _flash_messages as I've done, and ensure you have that first underscore (_) before 'flash...'. Tap 'Save'
Now in your _flash_messages.html.erb partial, use this
<% unless flash.blank? %>
<% flash.each do |type, message| %>
<div class="alert <%= flash_class(type.to_s) %>">
<button class="close" data-dismiss="alert">x</button>
<%= message %>
</div>
<% end %>
<% end %>
And in your application_helper.rb use this
def flash_class (type)
case type
when 'error'
"alert-error"
when 'notice'
"alert-info"
when 'alert'
"alert-block"
when 'success'
"alert-success
else
type.to_s
end
end
Then in your application.html.erb, add this as your first line in your first div
<%= render partial: 'layouts/flash_messages', flash: flash %>
Notice that we render the partial (any partial that is), without the 'starter' underscore(_), i.e before the word 'flash..'
You can check out this answer from teamtreehouse on displaying different alert cases.
Hope this helps!

Rails Submit Form Remote issues

I am trying to submit a form via remote: true in rails 3 and for some reason when I look at the response in the browser I only see the raw response instead of the JavaScript being interpreted.
Form:
<%= form_for #entry, url: contest_entries_path, remote: true, html: {id: "contest_form"} do |f| %>
Controller:
class ContestEntriesController < ApplicationController
respond_to :html, :js
def index
#entry = ContestEntry.new
#entry.build_school
respond_with #entry
end
def create
#entry = ContestEntry.new(params[:contest_entry])
respond_with #entry
end
end
Create.js.erb:
<% unless #entry.errors.any? %>
<% if #entry.parent? %>
$('body').find('#parents_message').show();
<% else %>
$('body').find('#falculty_message').show();
<% end %>
<% end %>
The response in the browser is the raw JavaScript response