I am trying to parse a JSON Object to insert values in table(MySQL). JSON is recived at server but it is unable to read the values to be inserted. Its inserting NULL values.
Below is snapshot from my rails console.
Started POST "/lists.json" for 192.168.1.9 at 2013-08-13 11:38:46 +0530
Processing by ListsController#create as JSON
Parameters: {"list"=>[{"amount"=>"120", "status"=>"done", "itemno"=>"w01", "na
me"=>"t01"}]}
WARNING: Can't verify CSRF token authenticity
(1.0ms) BEGIN
SQL (1.0ms) INSERT INTO `lists` (`amount`, `itemno`, `name`, `status`) VALUES
(NULL, NULL, NULL, NULL)
(103.0ms) COMMIT
The Create method in my lists_controller.rb is as below
def create
lists = params[:list].collect{|key,list_attributes| List.new(list_attributes)}
all_list_valid = true
lists.each_with_index do |list,index|
unless list.valid?
all_list_valid = false
invalid_list = lists[index]
end
end
if all_list_valid
#lists = []
lists.each do |list|
list.save
#lists << list
end
format.html { redirect_to #list, notice: 'List was successfully created.' }
format.json { render json: #list, status: :created, location: #list }
else
format.html { render action: "new" }
format.json { render json: #list.errors, status: :unprocessable_entity }
end
end
I am not sure why it is taking NULL values even though "Parameters" seems to have correct values. Please advise . Thanks.
See documentation for the collect method.
irb(main):008:0> parameters = {"list"=>[{"amount"=>"120", "status"=>"done", "itemno"=>"w01", "name"=>"t01"}]}
=> {"list"=>[{"status"=>"done", "amount"=>"120", "itemno"=>"w01", "name"=>"t01"}]}
irb(main):009:0> parameters["list"]
=> [{"status"=>"done", "amount"=>"120", "itemno"=>"w01", "name"=>"t01"}]
irb(main):010:0> parameters["list"].collect{|list| p list}
{"status"=>"done", "amount"=>"120", "itemno"=>"w01", "name"=>"t01"}
=> [nil]
Related
I receive the following error when attempting to update Stripe Connect accounts:
bad URI(is not URI?): /v1/accounts/{ "id": "acct_xxxxxxxxxxxxxxxxxx", "object": "account", "business_profile": { "mcc": null, "name": null, "product_description":
....
....
I am able to create accounts but updating them doesn't seem to work. I am using the same form and similar code in the controller. This is my update method in controller:
def update
unless (current_user || current_affiliate).stripe_account
redirect_to new_user_stripe_account_path and return
end
begin
#stripe_account_retrieve = Stripe::Account.retrieve((current_user || current_affiliate).stripe_account.acct_id)
stripe_account_params.each do |key, value|
if value.empty?
flash.now[:alert] = "Please complete all fields."
render 'edit' and return
end
end
if #stripe_account.account_type == "individual"
Stripe::Account.update(
#stripe_account_retrieve,
{
:country => stripe_account_params[:country],
:type => "custom",
:business_type => stripe_account_params[:account_type],
requested_capabilities: ['platform_payments'],
individual: {
address: stripe_account_params[:address_line1],
first_name: stripe_account_params[:first_name],
last_name: stripe_account_params[:last_name],
ssn_last_4: stripe_account_params[:ssn_last_4],
# phone: stripe_account_params[:business_tax_id],
dob: {
day: stripe_account_params[:dob_day],
month: stripe_account_params[:dob_month],
year: stripe_account_params[:dob_year]
},
address: {
line1: stripe_account_params[:address_line1],
city: stripe_account_params[:address_city],
state: stripe_account_params[:address_state],
postal_code: stripe_account_params[:address_postal]
},
},
tos_acceptance: {
date: Time.now.to_i,
ip: request.remote_ip
}
})
....
....
respond_to do |format|
#stripe_account = StripeAccount.find(params[:id])
if #stripe_account.update(stripe_account_params)
format.html { redirect_to #stripe_account, notice: 'Stripe account was successfully updated.' }
format.json { render :show, status: :ok, location: #stripe_account }
else
format.html { render :edit }
format.json { render json: #stripe_account.errors, status: :unprocessable_entity }
end
end
end
end
According to the docs, I don't see anything I am doing wrong...
https://stripe.com/docs/api/accounts/update
My edit in controller:
def edit
#stripe_account_retrieve = Stripe::Account.retrieve((current_user || current_affiliate).stripe_account.acct_id)
#stripe_account = StripeAccount.find(params[:id])
end
When i submit the update form (this is ahead of the error:)
Started PATCH "/stripe_accounts/27" for 127.0.0.1 at 2019-04-03 20:16:38 -0400
Processing by StripeAccountsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"3//b+Exxxf9xxxtagFbsdzMxxxW+wxxxx899FDLfMb/RxxxxQA==", "stripe_account"=>{"first_name"=>"seller21114", "last_name"=>"last2124", "ssn_last_4"=>"2222", "dob_month"=>"1", "dob_day"=>"10", "dob_year"=>"1912", "address_line1"=>"111 st", "address_city"=>"san fran", "country"=>"US", "address_state"=>"IL", "address_postal"=>"90210", "tos"=>"1"}, "2"=>"", "button"=>"", "id"=>"27"}
IS there anything I am doing wrong here with my code?
Stripe::Account.update(
#stripe_account_retrieve,... )
this should be
Stripe::Account.update(
#stripe_account_retrieve[:id], ...)
i.e., pass the ID of the Account object you retrieved, not the full object itself.
Or just pass the value of (current_user || current_affiliate).stripe_account.acct_id directly to Stripe::Account.update, since you don't seem to currently use the retrieved account for anything else so you may as well save youself a GET request :)
I have an ajax post to create a new Meeting. I want to convert the string meeting_time into a datetime format in the controller before save.
I have tried this, but it is still saving meeting_time as a string:
def create
requestor = current_user
#meeting_with_params = meeting_params
#meeting_time = #meeting_with_params[:meeting_time]
#meeting_time = #meeting_time.to_datetime
#meeting_with_params[:meeting_time] = #meeting_time
##meeting_with_params
#meeting = Meeting.new(#meeting_with_params)
respond_to do |format|
if #meeting.save
format.html { redirect_to home_url, notice: 'Your lex was successfully requested! Click Plan Meeting ' }
format.json { render :show, status: :created, location: #meeting }
else
format.html { render :new }
format.json { render json: #meeting.errors, status: :unprocessable_entity }
end
end
end
The params being passed look like this:
Started POST "/meetings" for 127.0.0.1 at 2016-10-31 11:45:44 -0400
Processing by MeetingsController#create as */*
Parameters: {"meeting"=>{"requestor_id"=>"1", "requestee_id"=>"2", "meeting_time"=>"2016-10-18 22:10:00", "accepted"=>"false", "status"=>"Active", "location"=>"Black Forest Restaurant", "location_address"=>"733 Fulton St, Brooklyn, NY 11217"}}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(0.1ms) begin transaction
SQL (1.1ms) INSERT INTO "meetings" ("requestor_id", "requestee_id", "meeting_time", "accepted", "location", "status", "location_address", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) [["requestor_id", 1], ["requestee_id", 2], ["meeting_time", "2016-10-18 22:10:00.000000"], ["accepted", "f"], ["location", "Black Forest Restaurant"], ["status", "Active"], ["location_address", "733 Fulton St, Brooklyn, NY 11217"], ["created_at", "2016-10-31 15:45:44.557266"], ["updated_at", "2016-10-31 15:45:44.557266"]]
And the ajax call in in .js file:
$.ajax({
url: '/meetings',
type: 'POST',
data: {
meeting: {
requestor_id: currentUserId,
requestee_id: requesteeId,
meeting_time: rubyDateTime,
accepted: false,
status: "Active",
location: meetingLocation,
location_address: meetingAddress
}
},
success: function(result) {
createNotification(currentUserId, "Your meeting was successfully requested.");
location.reload();
},
error: function(err) {
console.log(err);
}
})
How can I pull out meeting_time in the create controller, and change it to datetime before saving?
Thanks!!
****UPDATE
I know it is not saving correctly because I also have a method that compares today's date with the meeting_time, and if it has passed, to do something. When saving directly to the database, it recognizes the times that have passed. When saving through the POST, with the exact same string, it does not since it is comparing 2 different types. The comparision controller:
def requestor_review_meeting
#past_meetings = Meeting.where('meeting_time <= ? AND requestor_id= ? AND status = ? AND requestor_score < ?', DateTime.current, current_user, "Active", 1).order('meeting_time asc');
render json: #past_meetings
end
And in console:
> meeting_time
=> Tue, 18 Oct 2016 22:10:00 UTC +00:00
2.1.2 :012 > meeting_time.class
=> ActiveSupport::TimeWithZone
2.1.2 :013 > meeting_time.is_a?(DateTime)
=> false
2.1.2 :015 > meeting_time.is_a?(Time)
=> true
ActiveRecord automatically type casts all inputs so they match the database schema. So even though the allow you to save meeting_time as a string, it will convert it to a datetime on load. If you're interested you can read more here
There is no need to convert the datetime string into datetime before save, because it will be saved as datetime automatically.
Ex)
User.create('Test user', '1990-10-31 11:45:44 0000')
Consider first field is user name and second one is DOB. The second one will be automatically parsed as datetime.
first string from above '1990-10-31' treated as date
second string '11:45:44' treated as time and
third string '0000' denotes timezone
It seems, your code looks fine. If you try to print meeting_time by querying the post, it should be datetime object.
Update
As said by #Rocco, the following is enough to save the data as Rails will convert the date string to date automatically from params.
def create
requestor = current_user
#meeting_with_params = meeting_params
#meeting = Meeting.new(#meeting_with_params)
respond_to do |format|
if #meeting.save
format.html { redirect_to home_url, notice: 'Your lex was successfully requested! Click Plan Meeting ' }
format.json { render :show, status: :created, location: #meeting }
else
format.html { render :new }
format.json { render json: #meeting.errors, status: :unprocessable_entity }
end
end
end
I am trying to save the content of a html5 canvas to my Rails app. I found the
var url = canvas.toDataURL('image/png');
but I cant figure out how get that into my post/form.
Im using carrierwave to handle images but instead of uploading an image I want the user to draw one on the canvas.
I was thinking of something like setting the input file of the form to this content but that does not seem to be the way it works
Or maybe I should not be using the carrier wave?
thanks
simply place the content of url in an hidden field.
<input type="hidden" name="canvascontent" id="canvascontent" />
in javascript (with jquery):
var url = canvas.toDataURL('image/png');
$("#canvascontent").val(url);
The accepted answer didn't cover the carrierwave portion so here it is as I have it working in my app:
In my profile_images_contoller.rb I added the following functions:
# Convert base64 to binary
def split_base64(uri_str)
if uri_str.match(%r{^data:(.*?);(.*?),(.*)$})
uri = Hash.new
uri[:type] = $1 # "image/gif"
uri[:encoder] = $2 # "base64"
uri[:data] = $3 # data string
uri[:extension] = $1.split('/')[1] # "gif"
return uri
else
return nil
end
end
# Convert data uri to uploaded file. Expects object hash, eg: params[:profile_image]
def convert_data_uri_to_upload(obj_hash)
if obj_hash[:remote_image_url].try(:match, %r{^data:(.*?);(.*?),(.*)$})
image_data = split_base64(obj_hash[:remote_image_url])
image_data_string = image_data[:data]
image_data_binary = Base64.decode64(image_data_string)
temp_img_file = Tempfile.new("data_uri-upload")
temp_img_file.binmode
temp_img_file << image_data_binary
temp_img_file.rewind
img_params = {:filename => "data-uri-img.#{image_data[:extension]}", :type => image_data[:type], :tempfile => temp_img_file}
uploaded_file = ActionDispatch::Http::UploadedFile.new(img_params)
obj_hash[:image] = uploaded_file
obj_hash.delete(:remote_image_url)
end
return obj_hash
end
Then in my "create" action I passed convert_data_uri_to_upload(params[:profile_image]) to ProfileImage.new()
def create
#profile_image = ProfileImage.new(convert_data_uri_to_upload(params[:profile_image]))
#profile_image.imageable = #imageable
respond_to do |format|
if #profile_image.save
format.html { redirect_to #entity_redirect_edit_path, notice: 'Profile image was successfully created.' }
format.json { render json: #profile_image, status: :created, location: #profile_image }
else
format.html { render action: "new" }
format.json { render json: #profile_image.errors, status: :unprocessable_entity }
end
end
end
Source: http://www.davehulihan.com/uploading-data-uris-in-carrierwave/
I'm working with a Model called Recover. Prior to creating the model I would like to save the boolean attribute, Combo.occupied = true using the Recover.combo_id attribute as a reference.
It appears my SQL is executing the query properly, but it is not saving this attribute. How can I save Combo.occupied = true?
recover.rb:
before_create :checkin
protected
def checkin
x = Combo.find_by_id(combo_id).occupied =
true
end
Rails Console:
Started POST "/recovers" for 127.0.0.1
at 2011-01-06 17:07:24 -0800
Processing by
RecoversController#create as HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"o1Iu3Y9/rVBOZPoDUgVP/tRfQ8GxbdWC40DbPq9YxUE=",
"recover"=>{"combo_id"=>"4",
"email"=>"jz#marin.edu"},
"commit"=>"Create Recover"} Recover
Load (0.2ms) SELECT "recovers"."id"
FROM "recovers" WHERE
("recovers"."email" =
'justin.zollars#marin.edu') LIMIT 1
Recover Load (0.1ms) SELECT
"recovers"."id" FROM "recovers" WHERE
("recovers"."combo_id" = 4) LIMIT 1
Combo Load (0.5ms) SELECT "combos".*
FROM "combos" WHERE ("combos"."id" =
4) LIMIT 1 AREL (0.5ms) INSERT INTO
"recovers" ("locker_number", "email",
"requests", "created_at",
"updated_at", "combo_id") VALUES
(NULL, 'justin.zollars#marin.edu',
NULL, '2011-01-07 01:07:24.287072',
'2011-01-07 01:07:24.287072', 4)
Redirected to
http://localhost:3000/recovers/14
Completed 302 Found in 119ms
RecoversController#create
def create
#recover = Recover.new(params[:recover])
respond_to do |format|
if #recover.save
format.html { redirect_to(#recover, :notice =>
'Recover was successfully created.') }
format.xml { render :xml => #recover, :status => :created,
:location => #recover }
else
format.html { render :action => "new" }
format.xml { render :xml => #recover.errors, :status =>
:unprocessable_entity }
end
end
end
You need to call save for the new value to be written to the database:
def checkin
combo = Combo.find_by_id(combo_id)
combo.occupied = true
combo.save!
end
This is easier if you use update_attribute. Also, if you have a belongs_to relationship, you can dispense with the find:
belongs_to :combo
def checkin
if combo # true unless combo_id is nil
combo.update_attribute(:occupied,true)
end
end
Note that update_attribute bypasses validation. If you need to validate, use update_attributes(:occupied=>true) instead.
Here's the model file:
class ProfileTag < ActiveRecord::Base
def self.create_or_update(options = {})
id = options.delete(:id)
record = find_by_id(id) || new
record.id = id
record.attributes = options
puts "record.profile_id is"
puts record.profile_id
record.save!
record
end
end
This gives me the correct print out in my log. But it also says that there's a call to UPDATE that sets profile_id to NULL. Here's some of the output in the log file:
Processing ProfilesController#update (for 127.0.0.1 at 2010-05-28 18:20:54) [PUT]
Parameters: {"commit"=>"Save", "profile"=>{"id"=>"2", "password_confirmation"=>"", "username"=>"user2", "first_name"=>"user2_first", "password"=>"", "last_name"=>"user2_last"}, "authenticity_token"=>"...", "tag"=>"1", "id"=>"2"}
?[4;36;1mProfileTag Create (0.0ms)?[0m ?[0;1mINSERT INTO `profile_tags`
(`reputation_value`, `updated_at`, `tag_id`, `id`, `profile_id`, `created_at`) VALUES(0, '2010-05-29 01:20:54', 1, NULL, 4, '2010-05-29 01:20:54')?[0m
?[4;35;1mSQL (2.0ms)?[0m ?[0mCOMMIT?[0m
?[4;36;1mSQL (0.0ms)?[0m ?[0;1mBEGIN?[0m
?[4;35;1mSQL (0.0ms)?[0m ?[0mCOMMIT?[0m
?[4;36;1mProfileTag Load (0.0ms)?[0m ?[0;1mSELECT * FROM `profile_tags` WHERE (`profile_tags`.profile_id = 4) ?[0m
?[4;35;1mSQL (1.0ms)?[0m ?[0mBEGIN?[0m
?[4;36;1mProfileTag Update (0.0ms)?[0m ?[0;1mUPDATE `profile_tags` SET profile_id = NULL WHERE (profile_id = 4 AND id IN (35)) ?[0m
I'm not sure I understand why the INSERT puts the value into profile_id properly, but then it sets it to NULL on an UPDATE.
[Edit]
In ProfileController:
def update
#...stuff. Set tags array.
save_tags(tags) #These tags are correct. Verified by printouts before and after this call.
respond_to do |format|
if #profile.update_attributes(params[:profile])
flash[:notice] = 'Profile was successfully updated.'
#format.html { redirect_to(#profile) }
format.html { redirect_to :action=>'show' }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #profile.errors, :status => :unprocessable_entity }
end
end
end
def save_tags(tags)
profile = find_profile #finds the correct profile. And I confirm that it exists with a printout
tags.each do |t|
ProfileTags.create_or_update(:profile_id => profile.profile_id, :tag_id => t.id)
end
end
If you need more specifics, please let me know. I'm thinking that the save functionality does many things other than INSERTs into the database, but I don't know what I need to specify so that it will properly set profile_id.
Look at the line:
ProfileTags.create_or_update(:profile_id => profile.profile_id, :tag_id => t.id)
I believe you want to pass profile.id, and not profile.profile_id (which is probably null).
save! itself should't do this.
Maybe your problem is the name of the method. ActiveRecord::Base already have a method named create_or_update (see http://github.com/rails/rails/blob/2-3-stable/activerecord/lib/active_record/base.rb#L2913) which is called by save! - maybe replacing it causes this weird problem.
Try changing the name of your method to something else, it might help.
You aren't passing the id attribute to the create_or_update method in the first place, so you don't need to call it, just call create instead, like so:
def save_tags(tags)
profile = find_profile #finds the correct profile. And I confirm that it exists with a printout
tags.each do |t|
ProfileTag.create(:profile_id => profile.profile_id, :tag_id => t.id)
end
end