How to pass blob url to rails create method by ajax - ruby-on-rails

I want to upload a voice sound in my Rails project.
The recording works fine to download, but I can't send the data to rails server.
recorder && recorder.exportWAV(function (blob) {
var url = URL.createObjectURL(blob);
console.log(url);
$.ajax({
type: "POST",
url: "/voices",
data: {voice: {sound: url}}
});
});
In server log there is a post data, but sound was not created.
Started POST "/voices" for ::1 at 2015-12-08 20:43:16 +0900
Processing by VoicesController#create as */*
Parameters: {"voice"=>{"sound"=>"blob:http%3A//localhost%3A3000/3ad3859e-b960-44b8-ba18-20727e739bab"}}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Profile Load (0.3ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 LIMIT 1 [["user_id", 1]]
(0.2ms) BEGIN
SQL (0.5ms) INSERT INTO "voices" ("sound", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["sound", nil], ["created_at", "2015-12-08 11:43:16.254713"], ["updated_at", "2015-12-08 11:43:16.254713"]]
(0.6ms) COMMIT
Completed 500 Internal Server Error in 135ms (ActiveRecord: 3.4ms)
How can I pass the sound blob data to rails server?
voices_controller.rb
class VoicesController < ApplicationController
#voice = Voice.new(voice_params)
respond_to do |format|
if #voice.save
format.html { redirect_to root_path, notice: 'voice was successfully created.' }
format.json { render :show, status: :created, location: root_path }
else
format.html { render :new }
format.json { render json: #voice.errors, status: :unprocessable_entity }
end
end
def voice_params
params.require(:voice).permit(:sound, :user_id)
end
end
app/models/voice.rb
class Voice < ActiveRecord::Base
belongs_to :phrase
belongs_to :user
mount_uploader :sound, SoundUploader
end
Another attempt
recorder && recorder.exportWAV(function (blob) {
var url = URL.createObjectURL(blob);
console.log(url);
var formData = new FormData();
formData.append('voice[sound]', url);
$.ajax({
type: "POST",
url: "/voices",
data: formData
});
});
This codes ends up with a error Uncaught TYpeError: Illegal invocation.

Not sure, if you are trying to post the data correctly or have your models setup properly. you need to save your audio as a file, using File.open(filename, w)
SQL (0.5ms) INSERT INTO "voices" ("sound", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["sound", nil], ["created_at", "2015-12-08 11:43:16.254713"], ["updated_at", "2015-12-08 11:43:16.254713"]]
The SQL, is suggesting, that nothing is getting passed to "sound" field.
if you are passing it as a blob, you need to set the column accordingly, if not done entirely, however better option would be 2)
Send and save the audio data as a file. Have a look at link
formData.append('voice[sound]', url); # Comment this
formData.append('voice[sound]', blob); # This will send the actual data to your server and not the blob url. then your carrierwave will have the file data, which it can save.

Related

Use the image inserted in SummerNote in Ruby on Rails by linking CarrierWave and Cloudinary

I am in the process of creating a web app with Ruby on Rails.
I introduce SummerNote to make the article creation form user-friendly.
We have also introduced CarrierWave for user avatars.
I’m using Heroku in production.
However, Heroku is going to erase images after 24h. So I added Cloudinary as an addon for keeping images on Heroku.
But the images inserted in the text field in SummerNote was erased.
I am in trouble because I do not know how to link summer note, carrier wave and Cloudinary.
Does anyone know how to link to SummerNote and carrier wave and Cloudinary?
My CODE
summernote-init.coffee
sendFile = (file, toSummernote) ->
data = new FormData
data.append 'upload[image]', file
$.ajax
data: data
type: 'POST'
url: '/uploads'
cache: false
contentType: false
processData: false
success: (data) ->
img = document.createElement('IMG')
img.src = data.url
console.log data
img.setAttribute('id', "sn-image-#{data.upload_id}")
toSummernote.summernote 'insertNode', img
deleteFile = (file_id) ->
$.ajax
type: 'DELETE'
url: "/uploads/#{file_id}"
cache: false
contentType: false
processData: false
$(document).on 'turbolinks:load', ->
$('[data-provider="summernote"]').each ->
$(this).summernote
lang: 'ja-JP'
height: 400
callbacks:
onImageUpload: (files) ->
sendFile files[0], $(this)
onMediaDelete: (target, editor, editable) ->
upload_id = target[0].id.split('-').slice(-1)[0]
console.log upload_id
if !!upload_id
deleteFile upload_id
target.remove()
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave
process :convert => 'png'
end
uploaders_controller.rb
class UploadsController < ApplicationController
def create
#upload = Upload.new(upload_params)
#upload.save
respond_to do |format|
format.json { render :json => { url: #upload.image.url, upload_id: #upload.id } }
end
end
def destroy
#upload = Upload.find(params[:id])
#remember_id = #upload.id
#upload.destroy
FileUtils.remove_dir("#{Rails.root}/public/uploads/upload/image/#{#remember_id}")
respond_to do |format|
format.json { render :json => { status: :ok } }
end
end
private
def upload_params
params.require(:upload).permit(:image)
end
end
Referred to site
MyError
terminal
Started POST "/uploads" for ::1 at 2020-05-19 13:46:50 +0900
Processing by UploadsController#create as */*
Parameters: {"upload"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00007fc262966fc8 #tempfile=#<Tempfile:/var/folders/1v/z9ljm971349c50_qs5f5wy_h0000gn/T/RackMultipart20200519-19326-wz6m90.jpg>, #original_filename="jiyu.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"upload[image]\"; filename=\"jiyu.jpg\"\r\nContent-Type: image/jpeg\r\n">}}
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "uploads" ("image", "created_at", "updated_at") VALUES (?, ?, ?) [["image", "dtcgxdmlua3jd5ddxkpg.png"], ["created_at", "2020-05-19 04:46:50.050482"], ["updated_at", "2020-05-19 04:46:50.050482"]]
SQL (0.1ms) UPDATE "uploads" SET "image" = 'image/upload/v1589863584/dtcgxdmlua3jd5ddxkpg.png' WHERE "uploads"."id" = ? [["id", 7]]
(1.6ms) commit transaction
Completed 200 OK in 1710ms (Views: 0.2ms | ActiveRecord: 2.4ms)
Started GET "/posts/null" for ::1 at 2020-05-19 13:46:51 +0900
Processing by PostsController#show as HTML
Parameters: {"id"=>"null"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ? [["id", 0], ["LIMIT", 1]]
Completed 404 Not Found in 4ms (ActiveRecord: 0.6ms)
ActiveRecord::RecordNotFound (Couldn't find Post with 'id'=null):
my localhost
When I check the dashboard of Cloudinary, the image is saved but not displayed.
Can you tell me how to solve it?
Or what do I need to know?

Ruby on Rails createmethod doesn't work

I got a model day and a model task. day has many tasks. I'm using a nested_form for this. The user enters a time and two variables, which a caculated to an index. The first task, with the highest index has a starttime= 8am.
Now I want to order the tasks by the index and add every task's time to the previous task's starttime.
My attempt to solve this:
def create
#day = current_user.days.build(day_params)
#day.save
#day.tasks.each do |task|
task.index = task.ur**2 + task.imp
end
if current_user.worktype = 1
#tasks = #day.tasks.order(index: :desc)
x = 0
#tasks.each do |task|
if x = 0
task.starttime = Time.new.beginning_of_day + 8*60*60
x = task.id
else
task.starttime = #day.task.find(x).starttime + #day.task.find(x).time*60
x = task.id
end
end
elsif current_user.worktype = 2
...
end
#day.save
respond_to do |format|
if #day.save
format.html { redirect_to #day, notice: 'Day was successfully created.' }
format.json { render :show, status: :created, location: #day }
else
format.html { render :new }
format.json { render json: #day.errors, status: :unprocessable_entity }
end
end
end
But somehow starttime remains nil, when I want to print it out in the view
- #tasks.each do |task|
...
= task.starttime.strftime("%H:%M")
I checked it in rails console too.
consolelog for POST:
Started POST "/days" for ::1 at 2016-08-04 02:19:03 +0200
Processing by DaysController#create as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"YaLq2XBUMltzCpZxvKBp5NQGUgiw/Ockto1r0zy/dZHU3HVlp4lpcsH/b3Q9WYas97ENlwRiPzCUdOiBC06GbA==", "day"=>{"tasks_attributes"=>{"1470269934695"=> {"description"=>"1", "ur"=>"1", "imp"=>"1", "time"=>"1"
, "_destroy"=>"false"}, "1470269939280"=>{"description"=>"2", "ur"=>"3", "imp"=>"3", "time"=>"2", "_destroy"=>"false"}}}, "commit"=>"Create Day"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(0.0ms) begin transaction
SQL (3.5ms) INSERT INTO "days" ("user_id", "created_at", "updated_at") VALUES (?, ?, ?) [["user_id", 1], ["created_at", "2016-08-04 00:19:03.986762"], ["updated_at", "2016-08-04 00:19:03.986762"]]
SQL (0.0ms) INSERT INTO "tasks" ("description", "ur", "imp", "time", "day_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["description", "1"], ["ur", 1], ["imp", 1], ["time", 1], ["day_id", 11], ["created_at", "2016-08-04 00:19:03.992775"], ["updated_at", "2016-08-04 00:19:03.992775"]]
SQL (0.0ms) INSERT INTO "tasks" ("description", "ur", "imp", "time", "day_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["description", "2"], ["ur", 3], ["imp", 3], ["time", 2], ["day_id", 11], ["created_at", "2016-08-04 00:19:03.994776"], ["updated_at", "2016-08-04 00:19:03.994776"]]
(4.0ms) commit transaction
Task Load (0.5ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."day_id" = ? [["day_id", 11]]
Task Load (0.5ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."day_id" = ? ORDER BY "tasks"."index" DESC [["day_id", 11]]
(0.0ms) begin transaction
SQL (1.0ms) UPDATE "tasks" SET "index" = ?, "updated_at" = ? WHERE "tasks"."id" = ? [["index", 2], ["updated_at", "2016-08-04 00:19:04.006796"], ["id", 24]]
SQL (1.0ms) UPDATE "tasks" SET "index" = ?, "updated_at" = ? WHERE "tasks"."id" = ? [["index", 12], ["updated_at", "2016-08-04 00:19:04.009792"], ["id", 25]]
(3.6ms) commit transaction
(0.0ms) begin transaction
(0.0ms) commit transaction
Redirected to http://localhost:3000/days/11
Completed 302 Found in 39ms (ActiveRecord: 14.6ms)
EDIT
Building on #evanbike's answer I added a task.save everytime starttime is set. But nothing changed, so I tried and removed the If statement and now starttime is saved, but every task has the same time.
#tasks = #day.tasks.order(index: :desc)
x = 0
#tasks.each do |task|
if x = 0
task.starttime = Time.new.beginning_of_day + 8*60*60
task.save
x = task.id
else
task.starttime = #day.task.find(x).starttime + #day.task.find(x).time*60
task.save
x = task.id
end
end
#day.save
I hope someone can help me with this issue.
Thanks in advance.
When you do this, you are setting the index on the instance of the task in the #day association cache:
#day.tasks.each do |task|
task.index = task.ur**2 + task.imp
end
Then, when you do this:
#tasks = #day.tasks.order(index: :desc)
...it makes a db call (since you're calling order on it) and return new instances—that don't have index set. If you called sort or some array method, it would use the stored instances
I think the simplest would be to save the instances of tasks after you set each of the values. Calling sort on the association would probably work, but it seems brittle.

How to use find_or_create in create action?

I want to use find_or_create method in my game dates controller. I don't know how to use that method in create action, when params are in game_date_params. Any suggestion how can I extract date from game_date_params?
class GameDatesController < ApplicationController
before_action :authenticate_user!
before_action :authenticate_admin
def index
#game_dates = GameDate.all
#showcases = Showcase.joins(:game_dates)
end
def new
#game_date = GameDate.new
#game_date.referee_stats.build
end
def create
#game_date = GameDate.new(game_date_params)
if #game_date.save
redirect_to showcases_path
flash[:success] = "Game date created"
else
render 'new'
end
end
def show
#game_date = GameDate.find(params[:id])
end
def destroy
#game_date = GameDate.find(params[:id]).destroy
redirect_to root_url
flash[:success] = "Game date deleted"
end
private
def game_date_params
params.require(:game_date).permit(:date, referee_stats_attributes: [ :games_count, :showcase_id ])
end
This is output from POST action:
Started POST "/game_dates" for 127.0.0.1 at 2016-04-01 10:21:44 +0200
Processing by GameDatesController#create as HTML Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"jmuOmMCO/WTFIkxrsw5l2cPVMqZAl7h11f281I+OyoHH3ddwKoB9ANAqvQEHulR88c7fzQXnnIaxs8FChMCjqw==",
"game_date"=>{"date(1i)"=>"2016", "date(2i)"=>"4", "date(3i)"=>"1",
"referee_stats_attributes"=>{"0"=>{"games_count"=>"4",
"showcase_id"=>"1"}}}, "commit"=>"Create Game date"} User Load
(0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER
BY "users"."id" ASC LIMIT 1 [["id", 1]] GameDate Load (0.4ms)
SELECT "game_dates".* FROM "game_dates" WHERE "game_dates"."date" IS
NULL LIMIT 1 (0.2ms) BEGIN SQL (0.4ms) INSERT INTO "game_dates"
("date", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING
"id" [["date", "2016-04-01"], ["created_at", "2016-04-01
08:21:44.864669"], ["updated_at", "2016-04-01 08:21:44.864669"]] SQL
(0.4ms) INSERT INTO "referee_stats" ("games_count", "showcase_id",
"game_date_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4,
$5) RETURNING "id" [["games_count", 4], ["showcase_id", 1],
["game_date_id", 7], ["created_at", "2016-04-01 08:21:44.866897"],
["updated_at", "2016-04-01 08:21:44.866897"]] (18.1ms) COMMIT
Redirected to http://localhost:3000/showcases Completed 302 Found in
31ms (ActiveRecord: 20.1ms)
GameDate.find_or_create_by(game_date_params) would find record with ALL game_date_params, so you could do this by finding with specific params like date and assign rest of attributes to it via block. for example:
def create
# find or initialize the record
#game_date = GameDate.find_or_initalize_by(date: game_date_params[:date]) do |game_date|
# Accept nested attributes as well
game_date.assign_attributes(game_date_params)
end
if #game_date.save
redirect_to showcases_path
flash[:success] = "Game date created"
else
render 'new'
end
end
See also: find_or_create_by and AttributesAssignment API docs
It should be like :
def create
#game_date = GameDate.find_or_create_by(game_date_params)
if #game_date.present?
redirect_to showcases_path
flash[:success] = "Game date created"
else
render 'new'
end
end
Create action is for creating an object after the new action has been called and update action if the same but for edit. Mixing create & update logic i not a good idea. Maybe you should rethink what are you trying to do in your views.

Can't get user_id in database after Ajax call

In javascript I do an ajax call to the create function of deliveries_controller. This puts a new Delivery in the database with a product and quantity. I also try to put the current_user as user_id in the database, but for some reason it stays nil in the database.
My ajax call:
$.ajax({
type: "POST",
url: "/deliveries",
data: { delivery: {ingredient: "meel", quantity: "800", scenario_id: "3"} },
success: function(){
alert('Success!');
},
error: function(){
alert('No success');
}
});
I just pass some dummy data to test it all out.
and my deliveries_controller:
class DeliveriesController < ApplicationController
protect_from_forgery
def index
#storages = Storage.where(user_id: current_user)
end
def addQuantity
#storage = Storage.where(user_id: current_user.id)
#storage.update_all ("quantity = (quantity+200)")
redirect_to deliveries_url
end
def create
#delivery = Delivery.new(delivery_params)
respond_to do |format|
if #delivery.save
format.html do
render :nothing => true
end
format.json { render json: #delivery.to_json }
else
format.html { render :nothing => true} ## Specify the format in which you are rendering "new" page
format.json { render json: #delivery.errors } ## You might want to specify a json format as well
end
end
end
private
def delivery_params
params.require(:delivery).permit(:user_id, :ingredient, :quantity, :scenario_id)
end
end
New entries are created in the database, but whichever way I try to pass the user_id as param it isn't saved in the database.
I tried it like:
#delivery = Delivery.new(delivery_params, :user_id => current_user),
#user_id = current_user
#delivery = Delivery.new(delivery_params, #user_id)
and
params.require(:delivery).permit(:user_id, :ingredient, :quantity, :scenario_id).merge(user_id: current_user)
log:
Started POST "/deliveries" for 127.0.0.1 at 2014-11-03 12:59:37 +0100
Processing by DeliveriesController#create as */*
Parameters: {"delivery"=>{"ingredient"=>"meel", "quantity"=>"800", "scenario_id"=>"3"}}
Can't verify CSRF token authenticity
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' LIMIT 1
(0.0ms) begin transaction
SQL (0.2ms) INSERT INTO "deliveries" ("created_at", "ingredient", "quantity", "scenario_id", "updated_at") VALUES (?, ?, ?, ?, ?) [["created_at", "2014-11-03 11:59:37.253274"], ["ingredient", "meel"], ["quantity", 800], ["scenario_id", 3], ["updated_at", "2014-11-03 11:59:37.253274"]]
(12.5ms) commit transaction
Rendered text template (0.0ms)
Completed 200 OK in 24ms (Views: 0.8ms | ActiveRecord: 13.1ms)
but the user_id for Delivery stays nil. How would I pass the user_id from the current_user so it's saved in the database with the json I retrieve from the ajax call?
Thanks in advance
EDIT:
I fixed it the following way:
I send json data to javascript with content_tag:
= content_tag(:div,"", id: "storages", data:{url: Storage.where(user_id: current_user)})
this data is handled, and the user_id is suddenly accepted :)
thanks for the help!
Try this instead
#delivery = current_user.deliveries.new(delivery_params)
It should be
#delivery = Delivery.new(delivery_params.merge(user: current_user))
OR
#delivery = Delivery.new(delivery_params)
#delivery.user = current_user
Put current user_id on hidden field on HTML and send it with ajax like other params

Rails: Unpermitted parameters: id

I want use rails 4 as a server and post data to rails and then data is save to database. For this, I sen data by http and update method. But when data recieve in server and rails want to save data, I get Unpermitted parameters: id error. I post data by below code:
$scope.updateRadif = function(index, ID){
console.log(ID);
RadifSecure.update(index, {bolouk_id: 1, id: ID}).$promise.then(function(data){
//...
})
.catch(function (err) {
//...
})
};
app.factory('RadifSecure', function($resource) {
return $resource("/api/bolouks/:bolouk_id/radifs/:id", { bolouk_id: '#bolouk_id', id: "#id" },
{
'show': { method: 'GET', isArray: false },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
}
);
});
and I recieve data in rails server:
def update
#radif = Radif.find(params[:id])
respond_to do |format|
if #radif.update_attributes(radif_params)
format.json { head :no_content }
else
format.json { render json: #radif.errors, status: :unprocessable_entity }
end
end
end
private
def radif_params
params.require(:radif).permit(:bolouk_id, :describe, :price)
end
When I check the server log, the data is recieve ccorrectly, but rails doesn't permit to save in database:
Started PUT "/api/bolouks/1/radifs/16?describe=sdsad&price=3423432" for 127.0.0.1 at 2014-09-03 11:14:27 +0430
Processing by Api::V1::RadifsController#update as JSON
Parameters: {"bolouk_id"=>"1", "id"=>"16", "describe"=>"sdsad", "price"=>"3423432", "radif"=>{"id"=>"16", "bolouk_id"=>"1"}}
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 7 ORDER BY "users"."id" ASC LIMIT 1
Radif Load (0.0ms) SELECT "radifs".* FROM "radifs" WHERE "radifs"."id" = ? LIMIT 1 [["id", 16]]
Unpermitted parameters: id
(0.0ms) begin transaction
(0.0ms) commit transaction
Completed 204 No Content in 29ms (ActiveRecord: 0.0ms)
I try other code to solve this problem, but I'm not successful.
def update
#radif = Radif.find(params[:id])
radif.update!(radif_params)
end
Any one can help me to solve this problem?

Resources