ActionController:UnknownFormat respond_to do |format| - javascript

I'm trying to sign up Users using Devise, and render a JS file if a certain parameter is included in the sign-up. I'm getting the following error:
ActionController::UnknownFormat in RegistrationsController#create
ActionController::UnknownFormat
This is my "create" action (I marked the line the error pointed to):
if resource.persisted?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
if !params[:name].nil?
View.create(name: params[:name])
respond_to do |format| #THIS IS THE LINE WITH THE ERROR
format.js
end
else
respond_with resource, location: after_sign_up_path_for(resource)
end
else
respond_with resource, location: inactive_path_for(resource)
end
else
respond_with resource
end
The action is "create", in app/controllers/registrations_controller.rb. The JS file I'm trying to render is app/views/devise/registrations/create.js.erb.
My suspicion is that there's a problem with finding the file, but I can't figure out how to point it to the right route, or if that's even the right problem. Anyone have any thoughts?

Related

How to execute JS after saving a model in DB in Rails 6?

I’m Rails beginner and I’m a bit overwhelmed by the quite simple problem. I would like to do something like this:
Users fills in a form.
Taps on the submit button
Model is saved into database.
If the save operation was successful, execute a javascript.
The questions is: how to accomplish that in the best way possible in Rails 6? Should I use .js.erb files? Or should I have javascript put into webpacker?
I tried so far the following code, but without any success:
controller/jobs_controller.rb
def create
#job = current_user.jobs.build(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Success!' }
format.js {}
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
views/jobs/create.js.erb
alert('hello');
As it was pointed out by #max-pleaner I was missing remote: true in the form tag.

Rails respond_to throw ActionController::UnknownFormat

So, I'm trying to respond to an action with a js file.
def my_schedule
respond_to do |format|
format.js
end
end
In my view, I have 'my_schedule.js.erb' but it's not even executed, rails broke in the controller and throw me an error : ActionController::UnknownFormat, where I have the respond_to.
I tried to add
respond_to :js, :json, :html
at the beginning of my controller out of the actions but still not working.
Need help to debug this and understand how respond_to really works.
format.js will only respond to an xhr request. You can't trigger this response by just navigating to the route that points to this controller and method.
You can test the js.erb execution by changing the respond_to block to
def my_schedule
respond_to do |format|
format.html
format.js
end
end
Then create a my_schedule.html.erb file in the same view folder as the js.erb with the following contents
<%= link_to 'Test', my_schedule_path, data: { remote: true } %>
Note that you may need to adjust that path, I'm just guessing on that.
Then navigate to the same path you were trying to before. You should see a link which, when clicked, will fire the js response.

jQuery plugin for rails application images not loading

I'm using the jQuery plugin Raty for my ruby on rails 4.0 application and it seems to be working except the images for the stars aren't loading onto the screen.
So those images should be stars ^ When I mouseover them in the console while running web brick the following is outputted. (My scaffold is called reviews)
Started GET "/reviews/star-off.png" for 127.0.0.1 at 2014-03-28 14:15:42 -0400
Processing by ReviewsController#show as PNG
Parameters: {"id"=>"star-off"}
Review Load (1.3ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."id" = $1 LIMIT 1 [["id", "star-off"]]
Completed 404 Not Found in 2ms
ActiveRecord::RecordNotFound (Couldn't find Review with id=star-off):
app/controllers/reviews_controller.rb:67:in `set_review'
I currently have the star images in apps/assets/javascripts/images but have also tried to put them in app/assets/images and app/views/reviews but they still won't show up. Is my issue that they aren't in the correct directory (and if so, which directory should they be in) or do I need to add some code manually to my reviews controller? Thanks.
edit: So when I try to use it in my index page, I only get an error saying this, so I must have to do something to my routes.rb file?
ActionController::RoutingError (NNo route matches [GET] "/star-off.png")
edit: as requested here is routes.rb
ConcertReview::Application.routes.draw do
resources :reviews
get "review/index"
get "review/artist"
get "review/date"
get "review/venue"
get "review/genre"
get "review/comments"
root 'reviews#index'
get 'reviews/' => 'reviews#index'
end
and here's reviews_controller.rb (autogenerated from scaffold and have not modified)
class ReviewsController < ApplicationController
before_action :set_review, only: [:show, :edit, :update, :destroy]
# GET /reviews
# GET /reviews.json
def index
#reviews = Review.all
end
# GET /reviews/1
# GET /reviews/1.json
def show
end
# GET /reviews/new
def new
#review = Review.new
end
# GET /reviews/1/edit
def edit
end
# POST /reviews
# POST /reviews.json
def create
#review = Review.new(review_params)
respond_to do |format|
if #review.save
format.html { redirect_to #review, notice: 'Review was successfully created.' }
format.json { render action: 'show', status: :created, location: #review }
else
format.html { render action: 'new' }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reviews/1
# PATCH/PUT /reviews/1.json
def update
respond_to do |format|
if #review.update(review_params)
format.html { redirect_to #review, notice: 'Review was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reviews/1
# DELETE /reviews/1.json
def destroy
#review.destroy
respond_to do |format|
format.html { redirect_to reviews_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_review
#review = Review.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def review_params
params.require(:review).permit(:artist, :venue, :date, :genre, :sound, :stagePresence, :songSelection, :overallRating, :comments)
end
end
I had that very same problem on my project. The star images do belong in app/assets/images like you tried. However, you need to pass raty a path option like such:
$('div').raty({
readOnly: true,
halfScore: true,
score: 3,
path: '/assets'
});
This is working for me.
Also, if you have turbolinks on, you're going to have to tweek any $(document).ready(function () {...}); you might have. That was the problem I had right after this one.

Rails Edge Guides, AJAX example- why use both 'format.js' and 'format.json'?

In the "Working With Javascript" section of the Rails Edge Guides, an example is given of how to structure a 'create' action inside a 'User' controller, in order to integrate AJAX into the creation action:
# app/controllers/users_controller.rb
# ......
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.js {}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I've read here that both 'format.js' and 'format.json' are needed, because Javascript and JSON are different types of response. My question is, if both formats are specified in the first half of the 'create' action's if statement, why aren't both also needed in the 2nd half? Does this mean that Javascript uses the 'create.js.erb' file on success, but not on failure?
Yes, you are correct. Based on skimming the guide, it looks like you don't want to do anything with js in the case of failure. If you were to put
format.js {}
in the failure block as well, then it would try to execute the render #user portion, which would probably cause an error anyway.
If you really did want to execute a js block in the event of failure, you could just do it the same way as for the other formats.

How does "respond_with_navigational" work?

I'm working with Devise and DeviseInvitable to manage authentication in my app and I'm having some trouble adding AJAX support to InvitationsController#update. The controller in DeviseInvitable looks like this:
# invitations_controller.rb
# PUT /resource/invitation
def update
self.resource = resource_class.accept_invitation!(params[resource_name])
if resource.errors.empty?
set_flash_message :notice, :updated
sign_in(resource_name, resource)
respond_with resource, :location => after_accept_path_for(resource)
else
respond_with_navigational(resource){ render_with_scope :edit }
end
end
This works well when resource.errors.empty? == true and we execute:
respond_with resource, :location => after_accept_path_for(resource)
(i.e. invitations/update.js.erb is rendered and my javascript calls are made). The problem is that when resource.errors.empty? == false, and we execute:
respond_with_navigational(resource){ render_with_scope :edit }
the server says:
Rendered invitations/update.js.erb (1.4ms)
but my javascript calls are not being run. Can anyone explain what respond_with_navigational is supposed to be doing? I've been googling for hours and I haven't found an explanation of this api anywhere.
Thanks!
OK, I figure out what respond_with_navigational is doing. It's defined in the Devise base classes as such:
def respond_with_navigational(*args, &block)
respond_with(*args) do |format|
format.any(*navigational_formats, &block)
end
end
and, navigational_formats is defined in Devise as well:
# Returns real navigational formats which are supported by Rails
def navigational_formats
#navigational_formats ||= Devise.navigational_formats.select{ |format| Mime::EXTENSION_LOOKUP[format.to_s] }
end
So, it's basically a wrapper for respond_with(). In order to get this to work, I had to add the following to my InvitationsController:
respond_to :html, :js
and now, update.js.erb is being rendered properly.

Categories