Ruby On Rails:recieve json, parse and save in database - ruby-on-rails

I want post a json to rails controller and then save each of json to database by separate controller.
For this, I post this json to rails controller:
jsonList = {
"table": {column1:"column1",column2:"column2"},
"record": {name:"record 1"}
};
and recieve below json in rails controller:
Started POST "/api/calculate.json" for 127.0.0.1 at 2014-11-19 00:52:13 +0330
Processing by Api::V1::CalculateController#create as JSON
Parameters: {"table"=>{"column1"=>"column1", "column2"=>"column2"}, "record"=>{"name"=>"record 1"}, "calculate"=>{"table"=>{"column1"=>"column1", "column2"=>"column2"}, "record"=>{"name"=>"record 1"}}}
But I get below error in rails server log before I do anything:
Completed 500 Internal Server Error in 2ms
ActionView::MissingTemplate (Missing template api/v1/calculate/create, api/v1/base/create with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/Users/mgh/Documents/Maliat/sama/app/views"
):
actionview (4.1.6) lib/action_view/path_set.rb:46:in `find'
actionview (4.1.6) lib/action_view/lookup_context.rb:124:in `find'
actionview (4.1.6) lib/action_view/renderer/abstract_renderer.rb:18:in `find_template'
actionview (4.1.6) lib/action_view/renderer/template_renderer.rb:41:in `determine_template'
I search for this error, but don't find any usefull guide.
RailsController:
class Api::V1::CalculateController < Api::V1::BaseController
require 'json'
def create
....
end
end
I have another question. I want save each json to database by separate controller. For example I have a RecordController and use create action by below code:
def create
temp = Record.new(params[:record])
temp.save
end
and this type:
def create
temp = Record.create(params[:record])
end
but I get below error in server log:
ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError):
app/controllers/api/v1/calculate_controller.rb:6:in `create'
RecordController:
class Api::V1::RecordController < Api::V1::BaseController
require 'json'
def create
#data = Record.create(record_params)
#data.save
respond_with(#data)
end
private
def record_params
params.require(:record).permit(:name)
end
end
How can I fix this problems?

You need to review the use of strong parameters features in Rails. A similar question is also answered here: Active Model Forbidden attributes error

Why you wanna split JSON and send to two separate controllers instead of that create one controller method and parse your JSON and store into the database,
JSON format:
{
"table": {column1:"column1",column2:"column2"},
"record": {name:"record 1"}
};
Controller method:
def create_record_and_table
record = params[:record]
#record = Record.new(:name => record['name'])
#record.save
table = params[:table]
#table = Table.new(:column1 => table['column1'], :column2 => table['column2'])
#table.save
end

Related

Problem with sitemap.xml in Ruby on Rails app

I have Ruby on Rails app and I created sitemap.xml file (in public directory) with sitemap_generator gem but it can't be readable in production.
sitemap.rb
# Set the host name for URL creation
SitemapGenerator::Sitemap.default_host = "https://example.com"
SitemapGenerator::Sitemap.namer = SitemapGenerator::SimpleNamer.new(:sitemap, :extension => '.xml')
SitemapGenerator::Sitemap.create do
Category.find_each do |cat|
add category_path(cat), priority: 0.8, changefreq: 'daily', lastmod: cat.updated_at
end
Job.where(status: true).find_each do |job|
add job_path(job), priority: 0.6, lastmod: job.updated_at
end
end
errors_controller.rb
class ErrorsController < ApplicationController
def not_found
render status: 404
end
def unprocessable_entity
render status: 422
end
def internal_server_error
render status: 500
end
end
I have all views for each kind of errors but Heroku logs show me:
I, [2019-10-16T11:57:53 #4] INFO -- : Processing by ErrorsController#not_found as XML
I, [2019-10-16T11:57:53 #4] INFO -- : Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
2019-10-16T11:57:53 app[web.1]: Error during failsafe response: Missing template errors/not_found, application/not_found with {:locale=>[:en], :formats=>[:xml], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder, :haml]}. Searched in:
2019-10-16T11:57:53 app[web.1]: * "/app/app/views"
The command heroku run rails sitemap:refresh:no_ping is creating all links that I want but when I try to see the link https://mywebsite.com/sitemap.xml - I get 500 error and I can't see the content - I don't know why. I think it can be some problems with error controller because https://mywebsite.com/sitemap (without .xml) displays 404 page. With .xml it is 500 error.
On localhost everything works fine but in production mode on Heroku I have problems.
As I know, sitemap_generator creates sitemap.xml.gz file. Try open your-site.com/sitemap.xml.gz. Works on my project.

ActionController::UnknownFormat when uploading image with Dropzone

I have a new error regarding my Dropzone JS snippet. I use dropzone to upload images from an #Edit view.
One the images are created by another controller create action, I redirect to that very edit action.
This is where I get this new error :
Completed 406 Not Acceptable in 14ms (ActiveRecord: 1.1ms)
ActionController::UnknownFormat (PhotographesController#edit is missing a template for this request format and variant.
request.formats: ["application/json"]
request.variant: []):
actionpack (5.2.0) lib/action_controller/metal/implicit_render.rb:42:in `default_render'
actionpack (5.2.0) lib/action_controller/metal/basic_implicit_render.rb:6:in `block in send_action'
actionpack (5.2.0) lib/action_controller/metal/basic_implicit_render.rb:6:in `tap'
actionpack (5.2.0) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (5.2.0) lib/abstract_controller/base.rb:194:in `process_action'
.....
It used to work perfectly in the past. But since I have set this snippet in place I have done quite a few things: installing gem "serviceworker-rails" and deferring the javascript..
I have undeferred the Javascript but the error is still here. Is it related to the serviceworker gem ?
EDIT
Dropzone snippet inside Photographes#edit view (inline)
<script>
// Dropzone = dynamic
var AUTH_TOKEN=$('meta[name="csrf-token"]').attr('content');
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("div#mydropzone",{
url: "<%= photographe_photographephotos_path(#photographe.hashed_id) %>",
autoProcessQueue: false,
autoDiscover: false,
uploadMultiple: true,
addRemoveLinks: true,
// clickable: false,
parallelUploads: 12,
maxFilesize: 5,
maxFiles: 12,
acceptedFiles: 'image/jpg, image/jpeg, image/png',
params:{
'authenticity_token': AUTH_TOKEN
},
successmultiple: function(data,response){
$('#msgBoard').append(response.message).addClass("alert alert-success");
$('#msgBoard').delay(2000).fadeOut();
$('#fileslist').val(response.filesList);
$('#photographedit').off('submit').submit();
}
});
$('#photographedit').submit(function(e){
if(myDropzone.getQueuedFiles().length > 0){
e.preventDefault();
myDropzone.processQueue();
}
});
</script>
Then Photographephotos#create
def create
#photographe = Photographe.find_by(hashed_id: params[:photographe_hashed_id])
if params[:file].present?
uploaded_pics = params[:file]
maximum_images=12
available_images = maximum_images - #photographe.photographephotos.count
n_keys = uploaded_pics.keys.first(available_images)
filtered_pics = uploaded_pics.slice(*n_keys)
filtered_pics.each do |index,pic|
#image = #photographe.photographephotos.new
#image.image = pic
#image.image_file_name = "Copyright" + #photographe.professionnel.first_name.to_s + #photographe.professionnel.last_name.to_s + ".JPG"
#image.save
end
end
redirect_to edit_photographe_path(#photographe.hashed_id)
end
The redirect at the end returns (should return) to the Photographes#edit view. What is funny if it used to work properly ...
I see that people used to have same problem with Jbuilder as per github. I have updated Jbuilder gem with no success.
Also the pictures are properly updated by paperclip. I get this error from logs when the redirection fails at the end of the images creation.
It seems like the controller is trying to render a template in a format that doesn't exist, maybe you can try specifying the format explicitly like this:
redirect_to edit_photographe_path(#photographe.hashed_id), :format => :html
This may happen if you received a request in a specific format and want to render a template in a different one.
I'm not sure if, in your case, the :format option should go inside the _path() or the redirect_to() method. If the above doesn't work try this:
redirect_to edit_photographe_path(#photographe.hashed_id, :format => :html)

Template missing in render :file in ajax call when the file exists in Rails 4.2

Ajax is used for Bootstrap modal call. The js.erb file is called successfully and this js.erb file then should load html.erb residing in the same subdir as the js.erb is under biz_workflowz/app/views/application/. Here is the js.erb file:
$("#newworkflow .modal-content").html('<%= j render(:file => "/biz_workflowx/application/event_action.html.erb") %>');
$("#newworkflow").modal();
However the event_action.html.erb is never found. The error is raised in action_view/path_sets.rb:
def find(*args)
find_all(*args).first || raise(MissingTemplate.new(self, *args)) #find_all(*args).first returns NIL
end
The error is:
ActionView::Template::Error (Missing template c:/d/code/rails_proj/engines/biz_workflowx/app/views/application/event_action.html.erb with {:locale=>[:en], :formats=>[:js, :html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}. Searched in:
.......
* "C:/D/code/rails_proj/engines/biz_workflowx/app/views" #<<== did search the subdir but did not find anything
* "C:/D/code/rails_proj/engines/searchx/app/views"
* "C:/D/code/rails_proj/engines/commonx/app/views"
* "C:/D/code/rails_proj/engines/authentify/app/views"
* "C:/D/code/rails_proj/webportal"
* "C:/"
):
1: $("#newworkflow .modal-content").html('<%= j render(:file => "biz_workflowx/application/event_action.html.erb") %>');
2: $("#newworkflow").modal();
actionview (4.2.0) lib/action_view/path_set.rb:46:in `find'
Even with hardcoded path to the file event_action.html.erb, it still returns template missing. The similar js.erb code has been used in a few places for ajax call and I does not see why here it does not work. What could cause this error?
Updated
Here is the debug windows showing the biz_workflowz/app/views has been searched by resolver which does not see the file under /application/. Strange!
add event_action.html.erb file under c:/d/code/rails_proj/engines/biz_workflowx/app/views/application

Rails 5 render a template located outside of the 'views' directory

The following code
def show
render File.join(Rails.root, 'app', 'themes', 'default_theme', 'template'), layout: File.join(Rails.root, 'app', 'themes', 'default_theme', 'layout')
end
Works in rails 4.2.x but outputs the following error when using Rails 5.0.0
ActionView::MissingTemplate:
Missing template vagrant/app/themes/default_theme/template with {:locale=>[:nl], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby]}. Searched in:
* "/vagrant/app/views/themes/default_theme"
* "/vagrant/app/views"
* "/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/bundler/gems/devise-ebe65b516b38/app/views"
* "/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/devise-i18n-1.1.0/app/views"
It looks like it is searching only inside the 'app/views/*' directory. Is there a way to render a template located outside of the 'views' directory using rails 5.0.0, so it works just like it used to in previous Rails versions?
Start by appending the view path:
class ApplicationController
prepend_view_path( Rails.root.join('app/templates') )
# ...
end
You can then render templates in app/templates by calling:
render template: 'default_theme/template',
layout: 'default_theme/layout'
Using the template option tells rails to not append the path with the name of the controller.
You have to add the new folder to your configuration:
config.paths["app/views"].unshift(Rails.root.join("/vendor/myapp/views/myctrl").to_s)
Or your controller:
before_filter {
prepend_view_path(Rails.root.join("vendor/myapp/views/myctrl").to_s)
}
source

Get "ActionView::MissingTemplate" error, when I post json to rails controller from angular

I use angularjs in my new ruby on rails project. I create my view with angularjs and back end server with ruby on rails.
Now, I have a form in angular part, when user complete the form and click on send, I post a json like below to server:
$scope.jsonList = {
"form1": {name:"John",lastName:"Smart"},
"form2": {job:"student",age:"18"}
};
I post this json to a test action in rails controller. I put javascript (angularjs) and server side code below:
angularController:
//Services
.factory('Test', function($resource){
return $resource('/api/test.json', {}, {
create: { method: 'post'}
});
})
//Angular Controller
$scope.testResponse = Test.create(angular.toJson($scope.jsonList));
and routes.rb:
namespace :api, defaults: {format: :json} do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: :true) do
match '/test',to:'dropdowns#test', via: 'post'
end
end
and dropdownsController:
class Api::V1::DropdownsController < Api::V1::BaseController
def test
end
end
I do all this, but when I post json to rails server, I recieve json, but I get below error:
Started POST "/api/test.json" for 127.0.0.1 at 2014-11-22 17:11:10 +0330
Processing by Api::V1::DropdownsController#test as JSON
Parameters: {"form1"=>{"name"=>"John", "lastName"=>"Smart"}, "form2"=>{"job"=>"student", "age"=>"18"}, "dropdown"=>{"form1"=>{"name"=>"John", "lastName"=>"Smart"}, "form2"=>{"job"=>"student", "age"=>"18"}}}
Completed 500 Internal Server Error in 1ms
ActionView::MissingTemplate (Missing template api/v1/dropdowns/test, api/v1/base/test with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/Users/mgh/Documents/Maliat/sama/app/views"
):
actionview (4.1.6) lib/action_view/path_set.rb:46:in `find'
actionview (4.1.6) lib/action_view/lookup_context.rb:124:in `find'
actionview (4.1.6) lib/action_view/renderer/abstract_renderer.rb:18:in `find_template'
actionview (4.1.6) lib/action_view/renderer/template_renderer.rb:41:in `determine_template'
I can do any thing with json when I recieve in rails controller (like parse and puts on console and save in database with other controller), but at the end of controller, I get above error and I cannot post any response to angular part. Where is the problem?
How can I fix this error?
You are not explicitly rendering anything in the test method so rails is looking for a template to send back as a response. However, you don't have a json template in your api/v1/dropdowns/ folder (I think it will look for a file called test.json in your case).
You can solve this by either sending back a response explicitly, (check out this guide for more about rendering a response.
def test
render plain: "This is the response from 'test' method in DropDownsController"
end
or you want to return json of a model
def test
render json: #product
end
OR
You can put a template in your api/v1/dropdowns/ folder and rails will serve that instead. But the overall point is you need to send back a response.
For example:
api/v1/dropdowns/test.json.erb
{
"name" : "my name is greg or something"
}

Resources