ActionController::UnknownFormat in Controller ( #index) - ruby-on-rails

I have a link_to calling my #index. In this method lies a respond_to for a format.js so I can initiate some Ajax. Things is, when I look at the console I get an error 500 because of a "ActionController::UnknownFormat"
I have tested out differents solutions from older posts, but I can't figure out what I'm missing.
controler :
def index
respond_to do |format|
format.js { render partial: 'private/messages/load_more_messages' }
end
end
view :
<%= link_to "Load messages", private_messages_path(:conversation_id => conversation.id), remote: true %>
Does anyone have any thoughts on this ? It's supposed to be a text book case, but I've been hitting my heads against a brick wall with this one.

If you are loading a HTML partial try it like this:
def index
render partial: 'private/messages/load_more_messages'
end
Although i would recommend making a specific endpoint for fetching partials that you pass a route to since this might be something you do frequently in a project.
Something like this
def render_partial(partial_route)
render partial: partial_route
end

Well, after going around testing a wide range of ideas, I came back to my original thought and it worked perfectly. I don't know what went wrong the first time but now it is perfect.

Related

ActionController::UnknownFormat in HelpController#about

as a Ruby newbie I am still getting to grips with the language. I have created a broadcast controller for a simple database that is already being used in production. However, I am getting the above mentioned error. Below is the code I have used:
show.html.erb
<p id="notice"><%= notice %></p>
<%= link_to 'Edit', edit_broadcast_path(#broadcast) %> |
<%= link_to 'Back', broadcasts_path %>
Index.html.erb
index.html.erb
broadcasts_controller.rb
boradcast controller
help controller
class HelpController < ApplicationController
skip_before_action :authenticate_user!
def about
#render text: "Hello"
end
end
I am not sure if I am missing any files or configs, I will add them in the comments if need be. Thanks
Incoming requests may use headers or parameters to indicate to Rails what format, called "MIME type", the response should have. For instance, a typical GET request from entering a URL into your browser will ask for an HTML (or default) response. Other types of common responses return JSON or XML.
In your case your "about" action does not have any explicit responders, and because of that Rails can't match the requested format (which is what the error message is trying to convey). You will probably just want to add an HTML template app/views/help/about.html.erb with your content. Rails should identify the HTML template and handle things from there.
More info
In Rails you need to respond with a specific format, and it is easy to setup your controller actions to handle a variety of formats.
Here is a snippet you might find in a controller which can respond in 3 different ways.
respond_to do |format|
format.html { render "foo" } # renders foo.html.erb
format.json { render json: #foo }
format.xml { render xml: #foo }
end
You can see more examples and deeper explanations in the documentation here.
ActiveRecord helps because it comes with serializers out of the box which can create JSON and XML representations of your objects.

Using if .present? redirect

I feel like this is simple but I'm banging my head against the wall. I'm trying to tell my Rails app that if one parameter is present (signature in this example) that I want to redirect home. Here's my code:
<%= if #pc.signature.present? %><% redirect_to "pages#home" %><%end%>
I keep running into a syntax error. This is in the edit.html.erb file by the way.
Perhaps in your controller you didn't define #pc? also, use path instead of 'pages#home'. it should look more like this:
def edit
#pc = Pc.find(params[:id]) #or whatever your logic is
redirect_to root_path if #pc.signature.present?
# otherwise 'edit' template will be rendered
end
You need to do that on your action controller, not in the view
def your_action
if #pc.signature.present?
redirect_to 'your_path_or_url'
end
end

Rails: action and views

My question is : do we need a view file for each action in our controller?
(like if we defined a say_hello action in a controller, is it necessary to add say_hello.html.erb in his view directory?
I'll edit this to say it depends (with same content). If you plan on using that controller action as JS or JSON you don't need a view file. if you want one to share in multiple views, the file can contain a shared partial (which can be used in other views). This examples is shown by the generators scaffolding create examples like this. They are helpful if you are learning rails. Not great otherwise.
If you were to share a partial, you could have a partial named _form.html.erb and then inside your say_hello.html.erb file, it would just call:
<%= render 'form' %>
If you want to render JSON or JS files you can respond_to in your action:
respond_to do |format|
format.html # say_hello.html.erb
format.json { render json: #hello } #no file needed
format.js { render js: #hello }
#format.js   {} #do nothing... or use a little javascript in there...
# or have a file named say_hello.js.erb and use your #hello variable
end
Edit:
One last update. Your say_hello.js.erb file can do the anything on another view (if called remotely):
say_hello.js.erb
<% if #hello.attribute == "some value" %>
$('#div_in_another_view').show();
<% else %>
$('#div_in_somewhere_else').hide();
<% end %>
You can do jQuery and anything you want to the view calling it (as long as it's using AJAX).
End edit
Guides are great place to get started. Railscasts.com as well (even though Ryan isn't updating anymore).
Edit: A great example on the different options on the respond_to is on this rails guide regarding javascript
You can just pass javascript straight from that format.js call, or use a file if you need more complicated stuff. You don't need to do anything also. You could just have it return xml or nothing as well, depending on your use case.
No, it is not required. For example, you can render json or xml data from the controller without needed a view at all. This article explains it very well http://guides.rubyonrails.org/layouts_and_rendering.html
No you do not need a view for each action. BUT you do need a view for each action that will reach the end of the method.
If you return anywhere in the action then you are fine. A view is only required when an implicit render is called due to execution reaching the end of the action.
No, it's really up to you and it depends on what the action will actually do. Actions can render different types content types: text, json, html, xml... etc. Here's an example:
def show
render xml: #something
end
This action doesn't have a view, but it'll output an xml when called. It can also render different things based on the format of the call:
def show
respond_to do |format|
format.html do
redirect_to '/'
end
format.json do
render xml: #something
end
end
end
The action may also redirect (again, this one doesn't have a file):
def show
redirect_to '/'
end
At the end, it's really up to the programmer to handle how the action behaves, but if you leave it empty, it'll assume there's a file to render.

How to use Rails respond_with with a create action and javascript?

I've been reading about respond_with. and used it before in a couple of tutorials but dont really think I understand it fully.
The functionality I am trying to implement right now is this: I have a list of items of class Article, and each of them has a link to the create Favorite action. When the user clicks on it it the favorite instance is created and the user is redirected to the home page. I want this to work with AJAX without a page refresh, and execute some JavaScript on the article item to let the user know it's been favourited successfully. I've used the :remote => true attribute in the relevant link, so the action is executing remotely without problem, but I am a bit stuck on how to execute the action's .js.erb file.
I've done the following in the controller:
class FavouritesController < ApplicationController
before_filter :authenticate
respond_to :html, :js
def create
#article = Article.find_by_id(params[:article_id])
current_user.Favourites.create(:article => #article)
redirect_to root_path
end
The problem is, I dont know what parameter should i pass to respond_with. I've tried replacing the redirect with both respond_with #article, and respond_with without parameters, and while both of them work (the create.js.erb is called), I dont understand why...
I dont want to 'respond_with' anything, but only that when the action is executed via javascript, the create.js.erb gets called. Can anyone explain a) why does respond_with work anyway whatever I pass to it, and b) what is the right way to do this?
BTW, I am using Rails 3.0
EDIT: I understand it better if I use respond_to like in the following code, but I would like to understand respond_with better.
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
I ran across this question several times trying to solve a similar problem. It turns out my controller wasn't inferring the format as I assumed it would from the content type or the fact that it's an xhr request.
In any case, it worked when I switched from this:
contacts_path
To this:
contacts_path format: :json
I didn't care for that per se, so I changed my ajax call to include the dataType option like this (per jQuery ajax documentation):
$.ajax({url: contactUrl, type: 'POST', data: data, dataType: 'json' });
Hi Oalo go through the link below, it concisely explains the respond_with and respond_to. It lists all the options that you can pass to respond_with
http://ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with
Hope this answers your query

Form_for Gives Wrong Outputs After render :action=>'edit'

I think this question might have been asked before, but I honestly don't know how to search for it.
Basically, when I do a render :action => 'edit' in the update action in controller, somehow the view outputs the form as if it's a :action => 'new' page.
form_for gave the wrong action and f.submit gave wrong button text (it gave create instead of update)
edit:
relevant parts of controller
def edit
#user = User.find_by_email(current_user.email)
end
def update
old_password=params[:user].delete(:old_password)
#user=User.new(params[:user])
if User.find_by_email(#user.email).valid_password?(old_password)
logger.info 'Valid old password'
else
flash[:notice]='Invalid current password'
render :action=>'edit'
end
end
As discussed in the comments, #bassneck is right - while you are rendering the edit view, the form_for call looks at whether the object is persisted or not (#user.persisted?). This has the benefit in a lot of cases of being able to use one piece of form code for both new and edit views (I'll generally have a partial _form.html.erb that gets used for both situations).
In your case though, it isn't leading to the desired behaviour - so wwhat you need to do is make sure you're using the relevant user object. If you want to update a user, #user should be the object you want to update.

Resources