I'm playing about with the Ruby Feedzirra gem and have managed to acheive what I set out to do by using it in the controller.
Though everything I've seen has mentioned using it in the model. I was just wondering if this is ok to do in the controller, if not, how might I go about achieving the same in the model?
I want to submit a Feed URL and use that to update my model with the rest of the information about the feed.
Feeds_controller.rb
def create
#feed = Feed.new(params[:feed])
feed = Feedzirra::Feed.fetch_and_parse(#feed.feed_url)
#feed.title = feed.title
#feed.url = feed.url
#feed.last_modified = feed.last_modified
respond_to do |format|
if #feed.save
format.html { redirect_to #feed, notice: 'Feed was successfully created.' }
format.json { render json: #feed, status: :created, location: #feed }
else
format.html { render action: "new" }
format.json { render json: #feed.errors, status: :unprocessable_entity }
end
end
end
feed.rb
class Feed < ActiveRecord::Base
attr_accessible :feed_url, :last_modified, :title, :url
end
I'd make an instance method on the Model and use that in the controller so
class Feed < ActiveRecord::Base
def fetch!
feed = Feedzirra::Feed.fetch_and_parse(feed_url) # probably want some eror handling here
title = feed.title
url = feed.url
last_modified = feed.last_modified
self #or nil if you like
end
end
then your controller thins down to
def create
#feed = Feed.new(params[:feed])
#feed.fetch!
respond_to do |format|
if #feed.save
format.html { redirect_to #feed, notice: 'Feed was successfully created.' }
format.json { render json: #feed, status: :created, location: #feed }
else
format.html { render action: "new" }
format.json { render json: #feed.errors, status: :unprocessable_entity }
end
end
end
The cool thing here is that if this gets too slow you can use something like Resque to run this in the background and just return a "your request is being processed" message to the user, then alert them asynchronously when the the request is done (might not work so well for the json request)
You really don't want to use something like a RSS parser in your controller. That will slow the responsiveness of that URL and your server.
Instead, run the RSS parser in a separate application, or at least a separate thread, and store the retrieved feeds in a database table for rapid access.
Related
We use below ruby and rails version -
Ruby 2.7.3 Rails 6.1.3.2
While creating a new user it throws the below error -
NoMethodError (undefined method `marshal_dump' for #ActiveModel::Errors:0x0000000006fcbba0 Did you mean? marshal_load):
app/controllers/user_controller.rb:33:in `create'
Below Create method defined in the controller -
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I am making an app with a todo list and I recently tried to add the ability to build out the todo lists from the user.
I ran into a problem when I changed the following lines.
def new
#todo_list = current_user.todo_lists.build
end
def create
#todo_list = current_user.todo_lists(todo_list_params)
respond_to do |format|
if #todo_list.save
format.html { redirect_to #todo_list, notice: 'Todo list was successfully created.' }
format.json { render :show, status: :created, location: #todo_list }
else
format.html { render :new }
format.json { render json: #todo_list.errors, status: :unprocessable_entity }
end
end
end
I was using the following code.
def new
#todo_list = TodoList.new
end
def create
#todo_list = TodoList.new(todo_list_params)
respond_to do |format|
if #todo_list.save
format.html { redirect_to #todo_list, notice: 'Todo list was successfully created.' }
format.json { render :show, status: :created, location: #todo_list }
else
format.html { render :new }
format.json { render json: #todo_list.errors, status: :unprocessable_entity }
end
end
end
I have added a user id to the todo items by creating a new migration and migrated the data base and created an association to the user for the posts. Not really sure what's going wrong but any help would be greatly appreciated.
Thanks.
Change this line:
#todo_list = current_user.todo_lists(todo_list_params)
into this:
#todo_list = current_user.todo_lists.build(todo_list_params)
In my rails app I have a ajax request to the server, to store some data. This used to work without any problem, but now I get an error:
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/reservations_controller.rb:45:in `create'
As following is the controller and my javascript file where I declare the datatype do be JSON
class ReservationController < ApplicationController
respond_to :html, :json
def create
...
respond_to do |format|
if #reservation.save
format.html do
redirect_to '/'
end
format.json { render json: #reservation.to_json }
else
render 'new'
end
end # respond_to
end # create
end # ReservationController
function.js
$.ajax({
url: url_link,
dataType: 'json',
type: 'POST',
data: dataToSend
})
The complete error log is:
Completed 406 Not Acceptable in 45ms
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/bookings_controller.rb:45:in `create'
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.5ms)
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.8ms)
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.8ms)
Rendered /Users/tiagovieira/.rvm/gems/ruby-2.0.0-p451/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (9.6ms)
Update the create action as below:
def create
...
respond_to do |format|
if #reservation.save
format.html do
redirect_to '/'
end
format.json { render json: #reservation.to_json }
else
format.html { render 'new'} ## Specify the format in which you are rendering "new" page
format.json { render json: #reservation.errors } ## You might want to specify a json format as well
end
end
end
You are using respond_to method but anot specifying the format in which a new page is rendered. Hence, the error ActionController::UnknownFormat .
You can also modify your config/routes.rb file like:
get 'ajax/:action', to: 'ajax#:action', :defaults => { :format => 'json' }
Which will default the format to json.
It is working fine for me in Rails 4.
Or if you want to go even further and you are using namespaces, you can cut down the duplicates:
namespace :api, defaults: {format: 'json'} do
#your controller routes here ...
end
with the above everything under /api will be formatted as json by default.
There is another scenario where this issue reproduces (as in my case). When THE CLIENT REQUEST doesn't contain the right extension on the url, the controller can't identify the desired result format.
For example: the controller is set to respond_to :json (as a single option, without a HTML response)- while the client call is set to /reservations instead of /reservations.json.
Bottom line, change the client call to /reservations.json.
This problem happened with me and sovled by just add
respond_to :html, :json
to ApplicationController file
You can Check Devise issues on Github: https://github.com/plataformatec/devise/issues/2667
Well I fond this post because I got a similar error.
So I added the top line like in your controller
respond_to :html, :json
then I got a different error(see below)
The controller-level respond_to' feature has been extracted to theresponders` gem. Add it to your Gemfile to continue using this feature: gem 'responders', '~> 2.0' Consult the Rails upgrade guide for details.
But that had nothing to do with it.
I got this error when trying to render an XML response - I had to change my template name from index.html.erb to index.xml.erb and then it worked.
mine was fixed because i didnt have / / in the scope,
i had this (getting error for json):
Rails.application.routes.draw do
scope '(:base_url)', base_url: #{ENV.fetch('BASE_URL').to_s} do
...
end
end
instead of this (fixed):
Rails.application.routes.draw do
scope '(:base_url)', base_url: /#{ENV.fetch('BASE_URL').to_s}/ do
...
end
end
I'm getting a "406 Not Acceptable in 13ms (ActiveRecord: 0.6ms)" error when I tried to implement ajax. Code works in normal html without any respond_to blocks. I've narrowed down the issue to the respond_to blocks and I'm stumped now. None of the other solutions on SO & google of the same error seem to apply or work.
What causes a 406 error when using the respond_to block whether html only or ajax/js included?
How to fix the 406 error?
Is it ok to use redirect_to in the respond_to block for format.html as shown in code below?
Let me know if you need more info.
View (haml):
Normal html code
%div.control-group.controls
= button_to "Delete Gcal User", #gcal_user, method: :delete, class: "btn btn-danger"
AJAX code
%div.control-group.controls
= button_to "Delete Gcal User", #gcal_user, method: :delete, remote: true, class: "btn btn-danger"
JS code (coffeescript) for AJAX
$('#calendar').empty();
Controller:
class GcalUsersController < ApplicationController
def destroy
#gcal_user = current_user.gcal_user
# if #gcal_user.delete
# flash[:notice] = "#{#gcal_user.username} deleted"
# end
# redirect_to user_root_path # <-- using this in html mode, app works i.e. no 406 error
respond_to do |format|
format.html { redirect_to(user_root_path) } # <-- using this in html mode instead of above line, app fails i.e. 406 error
# format.js # <-- using this in ajax mode, app fails i.e. 406 error
end
end
end
You want to respond with "json", not with "js" (which means JavaScript here). jquery_ujs, the gem that adds the functionality for method: :delete, expects JSON.
def destroy
#gcal_user = current_user.gcal_user
#gcal_user.delete
respond_to do |format|
format.html { redirect_to user_root_path }
format.json { head :no_content }
end
end
The problem was caused by routes. Using the singular resource :gcal_user instead of the plural resources :gcal_users caused the URL to be formated differently. The singular resource uses the "/gcal_user.[id]" which caused the respond_to block to think the format must be in ".[id]" instead of the ".js" or ".html".
See Respond_to does not redirect, gives 406 Not Acceptable error
I have the following controller action:
def create
#board = Board.new(params[:board])
respond_to do |format|
if #board.save
set_board_session #board
set_new_board
format.js { render :action => "show" } #<== here I want to render html no js
else
format.js { render :action => "new" }
end
end
end
I want to render the show.html.erb action not the show.js.erb action for an ajax request.
How can I do this?
UPDATE
This seems to work for me:
I put this in my application controller:
def redirect_to(options = {}, response_status = {})
if request.xhr?
render(:show) {|page| page.redirect_to(options)}
else
super(options, response_status)
end
end
Now I can redirect with an Ajax call.
format.js {redirect_to #board}
Thanks to this forum:
Set dataType to "html" in your AJAX request and Rails will correctly handle AJAX request and render html, not js.
This seems to work for me:
I put this in my application controller:
def redirect_to(options = {}, response_status = {})
if request.xhr?
render(:show) {|page| page.redirect_to(options)}
else
super(options, response_status)
end
end
Now I can redirect with an Ajax call.
format.js {redirect_to #board}