Gurus,
Need help with RoR API
I see all the required parameters are being sent, however the server does not like one or some of it.
controller:
def create
#account = Account.new(account_params)
if #account.save
render json: #account, status: :created, location: #account
else
render json: #account.errors, status: :unprocessable_entity
end
end
def account_params
params.require(:account).permit(:client_id, :currency_id, :name, :type, :institution)
end
call looks like this:
Started POST "/accounts?name=TD-Trading¤cy_id=1&institution=TD%20Waterhouse&type=Investment&client_id=1" for ::1 at 2020-11-27 01:16:08 -0700
Processing by AccountsController#create as /
Parameters: {"name"=>"TD-Trading", "currency_id"=>"1", "institution"=>"TD Waterhouse", "type"=>"Investment", "client_id"=>"1"}
Client Load (0.4ms) SELECT "clients".* FROM "clients" WHERE "clients"."email" = $1 ORDER BY "clients"."id" ASC LIMIT $2 [["email", "akaghzi#gmail.com"], ["LIMIT", 1]]
Completed 400 Bad Request in 271ms (ActiveRecord: 0.4ms | Allocations: 1706)
ActionController::ParameterMissing (param is missing or the value is empty: account):
app/controllers/accounts_controller.rb:55:in account_params' app/controllers/accounts_controller.rb:21:in create'
This piece of code:
def account_params
params.require(:account).permit(:client_id, :currency_id, :name, :type, :institution)
end
Is saying that it expects an account hash with inside that the attributes. Your logs shows you send all attributes not wrapped inside an account hash.
You can solve this by wrapping the params inside a account hash or remove the require(:account) part from the account_params.
Related
I have my form to save to my Stripe_account table. I recently nested the resources and now the form won't save to my database tables. I have it still working with the Stripe API and working there though.
What in my code is lacking?
User Model:
has_one :stripe_account
Stripe_account Model:
belongs_to :users
Stripe_account controller:
def new
#stripe_account = StripeAccount.new
#user = User.find(params[:user_id])
end
def create
#stripe_account = StripeAccount.new(stripe_account_params)
#user = User.find(params[:user_id])
acct = Stripe::Account.create({
.....
.....
#stripe_account.id = current_user.id
#stripe_account.acct_id = acct.id
respond_to do |format|
# #user = User.find(params[:id])
if #stripe_account.save
# current_user = #user
#user.stripe_account = acct.id
format.html { redirect_to new_bank_account_path, notice: 'Stripe account was successfully created.' }
format.json { render :show, status: :created, location: #stripe_account }
else
format.html { render :new }
format.json { render json: #stripe_account.errors, status: :unprocessable_entity }
end
end
end
View:
<%= form_for ([#user, #stripe_account]) do | f | %>
Routes:
resources :users do
resources :stripe_accounts
end
#added for testing
get 'stripe_' => "stripe_account#create"
get 'stripe_new' => "stripe_account#new"
Here's my routes maybe can help?: https://pastebin.com/RVWd2Qq9
Now even though I don't have the "bankaccount" controller or models set up correctly yet, shouldn't it be at least attempting to go there and saving the stripe_account? Just making sure that's not the issue. But it appears it's failing because a new form reloads.
The API is successfully going through as well and the accounts are appearing within stripe, just not my own database.
What in my programming is wrong?
Update to add cmd response:
Started POST "/users/2/stripe_accounts" for 127.0.0.1 at 2018-11-10 00:11:26 -0500
Processing by StripeAccountsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"nz1234567890iJuFwsm/Z4ylhE6zoGdWN6QCfWtDZTH1sxZu/WCdWMKBGkc4zoZ2dOgk9c8UDwRzgqdxrT/sA==", "stripe_account"=>{"account_type"=>"individual", "business_name"=>"", "business_tax_id"=>"", "first_name"=>"Dill", "last_name"=>"Pickles", "ssn_last_4"=>"1234", "dob_month"=>"3", "dob_day"=>"4", "dob_year"=>"1917", "address_line1"=>"198 berry avenue", "address_city"=>"san fran", "address_state"=>"CA", "address_postal"=>"90213", "tos"=>"1", "id"=>"2"}, "full_account"=>"{:value=>\"true\"}", "button"=>"", "user_id"=>"2"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ app/controllers/stripe_accounts_controller.rb:49
(0.1ms) begin transaction
↳ app/controllers/stripe_accounts_controller.rb:91
(0.1ms) rollback transaction
↳ app/controllers/stripe_accounts_controller.rb:91
Rendering stripe_accounts/new.html.erb within layouts/application
Rendered stripe_accounts/_account_form.html.erb (9.4ms)
Rendered stripe_accounts/new.html.erb within layouts/application (12.5ms)
Rendered layouts/_navbar.html.erb (1.9ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 3202ms (Views: 190.0ms | ActiveRecord: 2.4ms)
Validation failed: User must exist
You can either use optional :true to resolve the error
#stipe_account.rb
belongs_to :user, optional: true
#^ should be singular
OR
Assign the user_id in the create action like so
#stripe_account.user_id = current_user.id #add this line
Update:
undefined method `user_id=' for StripeAccount:0x001234f4c58692ae8 Did
you mean? user="
The error is because you don't have user_id column in stripe_accounts table. Generate a migration that will do the job for you
rails g migration add_user_id_to_stripe_accounts user_id:integer
and do rails db:migrate
I have a Rails model called user that has a birthday field with type date in Postgres.
My first issue is that I'm not sure how to update the value of a user. If I pass in a string like "10/10/1980", it does not update.
The second issue is that even when the birthday is not updated, Rails returns true for the User.update(user_params) action
My two questions:
How can I update a date field?
How can I make sure that rails throws an error if an incorrect date is passed in?
How can I update a date field?
Update method from controller below. Fairly standard from scaffolding.
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
puts(user_params)
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
Edit: Params:
def user_params
params.require(:user)
.permit(:points, :payment_option, :first_name, :last_name,
:payment_email, :phone_number, :facebook_id, :profile_pic_url,
:locale, :timezone, :gender, :email, :country, :city,
:age_group, :birthday, :employment_status, :occupation,
:education_level, :income_bracket)
end
Rails log (note that I added a puts(user_params) after the update statement.
Started PATCH "/api/v1/users/1" for 127.0.0.1 at 2017-12-07 19:16:37 +0800
Processing by UsersController#update as JSON
Parameters: {"user"=>{"birthday"=>"12dsafkljfsldk"}, "id"=>"1"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Can't verify CSRF token authenticity.
{"birthday"=>"10/10/1900"}
(0.2ms) BEGIN
(0.1ms) COMMIT
Rendering users/show.json.jbuilder
Rendered users/_user.json.jbuilder (0.6ms)
Rendered users/show.json.jbuilder (1.6ms)
Completed 200 OK in 31ms (Views: 5.9ms | ActiveRecord: 3.1ms)
I was hoping that I could use before_update to parse the date string into a Date object before saving, but it doesn't look like self.birthday is even showing up in the model.
Place this line in your ApplicationController
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
If it doesn't work then. Try to skip the action
skip_before_action :verify_authenticity_token
I am using paperclip-5.0.0, and Rails 5.0.2.This is my code in controller
class PawsController < ApplicationController
before_action :set_paw, only: [:show, :edit]
def index
#paws = Paw.all
end
def show
end
def new
#paw = Paw.new
end
def edit
end
def create
#paw = Paw.new(paw_params)
respond_to do |format|
if #paw.save
format.html { redirect_to #paw, notice: 'Paw was successfully created.' }
format.json { render :show, status: :created, location: #paw }
else
format.html { render :new }
format.json { render json: #paw.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_paw
#paw = Paw.find(params[:id])
end
def paw_params
params.require(:paw).permit(:avatar,:name) if params[:avatar]
end
end
Avatar here is the column for paw which stores images.In model I have added required validations for paperclip and validation for presence of name.
Problem: In rails console I am successfully able to open the image file from my computer and add it to the paw model i.e. #paw.save returns true in console, but in the browser it redirects me to the new_paw_url with two errors.
Name can't be blank. and
Avatar can't be blank.
There are no exceptions or errors thrown in between the process.I have no idea how should I fix this.
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by PawsController#create as HTML
Parameters: {"utf8"=>"✓","authenticity_token"=>"zKpb2XFEG4FqX3aVQx9oyyGI9x2NpmF+lmt4eZy/3p3VZr2eWYvHLaEjS5AvisJ6iEbRm61SJkJSuTpMx4c0JA==", "paw"=>{"name"=>"Sheru", "gender"=>"Male", "breed"=>"", "dob"=>"", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x005608576e1f30 #tempfile=#<Tempfile:/tmp/RackMultipart20170323-14343-1o95nqx.jpg>, #original_filename="art.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"paw[avatar]\"; filename=\"art.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Upload"}
(0.1ms) begin transaction
(0.1ms) rollback transaction
(0.1ms) begin transaction
(0.1ms) rollback transaction
Rendering paws/new.html.erb within layouts/application
Rendered paws/_form.html.erb (15.8ms)
Rendered paws/new.html.erb within layouts/application (17.3ms)
Rendered layouts/_navbar.html.erb (0.6ms)
Completed 200 OK in 326ms (Views: 287.5ms | ActiveRecord: 2.0ms)
Feel free to ask for any other code snippets from me.
Your paw_params method is breaking it. Remove the if statement and it should work. The problem you're having is that the params you're recieving through your controller are nested in the params[paw] hash and not the params hash. Your paw_params if statement should be
params.require(:paw).permit(:avatar,:name) if params[:paw][:avatar]
Look at the console of your params hash and you'll see that Rails will nest all params submitted via a form helper within the class name of the object. In this case it's paw.
"paw"=>{"name"=>"Sheru", "gender"=>"Male", "breed"=>"", "dob"=>"", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x005608576e1f30
More obviously:
params[:name] #nil
params[:paw][:name] #"Sheru"
Also, it's not a good practice to add conditionals for strong_paramaters based on the presence of certain attributes. If someone submits a name without an avatar, the name wont be permitted due to strong_parameters but would give the user poor feedback. Instead you should use validations in your Paw model that requires the presence of both the name and avatar.
I found several topics related , but couldn't figure out how to solve this problem,
This is my code
<%= f.label :projeto %><br>
<%= f.collection_select :projeto, Projeto.order(:id), :id, :name, include_blank: true %>
model => task belongs_to projeto and projeto has_many tasks
Full Error:
ActiveRecord::AssociationTypeMismatch at /tasks/1
Projeto(#69996814678740) expected, got String(#69996762580840)
Database is set to t.references.
Task_controller
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task, notice: 'Task was successfully updated.' }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def task_params
params.require(:task).permit(:seq, :descr, :seqpai, :typo, :hour, :projeto)
end
Started PATCH "/tasks/1" for 127.0.0.1 at 2015-06-18 14:30:23 -0300
Processing by TasksController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Is7YTC0v5OONEEsIgOvmI+CEuVYG/WsoKWzskGippD2eOwthKVHb2dI+S19GkkI9aU0IwTrzwERlLq2ybWbGxw==", "task"=>{"seq"=>"0", "descr"=>"Projeto", "seqpai"=>"", "typo"=>"Analitica", "hour"=>"12", "projeto"=>"1"}, "commit"=>"Update Task", "id"=>"1"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = ? LIMIT 1 [["id", 1]]
(0.2ms) begin transaction
(0.1ms) rollback transaction
Completed 500 Internal Server Error in 25ms (ActiveRecord: 0.8ms)
Normally this is caused by assigning a string to something expecting a model association. For example:
# Not allowed, `project=` expects a Project model
#task.project = params[:project_id]
# Converts parameter into model, but may throw exception
#task.project = Project.find(params[:project_id])
# Direct assignment, requires validation on model level
#task.project_id = params[:project_id]
I changed the View for
<%= f.label :projeto_id %>
and permited in controller projeto_id
Then worked Fine,
Thanks everyone for the hint.
Authlogic seems to be ignoring the password parameter when creating a new user. Here's my users_controller class:
class Api::V1::UsersController < ApplicationController
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.json { render :json => #user, :status => :created}
else
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:username, :email, :password)
end
end
And my user model:
class User < ActiveRecord::Base
acts_as_authentic do |c|
c.require_password_confirmation = false
end
end
When I send a POST request to /api/v1/users/ with a username, email and password parameter, authlogic says that the password cannot be blank even though it isn't. Here's whats printed out by rails:
Started POST "/api/v1/users/" for 127.0.0.1 at 2013-06-22 00:03:30 -0400
Processing by Api::V1::UsersController#create as */*
Parameters: {"email"=>"someemail#website.com", "password"=>"[FILTERED]", "username"=>"myUser", "user"=>{"username"=>"myUser", "email"=>"someemail#website.com"}}
(0.2ms) BEGIN
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('someemail#website.com') LIMIT 1
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER('myUser') LIMIT 1
User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."persistence_token" = '7b72bab3627914d33e83e4efe1c5a9dab190750efb227698c8b5b6be7a7ccf118160d8e12623078543e0f4e5f31eb30828799cb0d97fb2af195daee894c79902' LIMIT 1
(0.2ms) ROLLBACK
Completed 422 Unprocessable Entity in 33ms (Views: 0.2ms | ActiveRecord: 3.2ms)
I'm using the latest authlogic and Ruby 2/Rails 4.
Take a look at an excerpt from Rails log:
{"email"=>"someemail#website.com", "password"=>"[FILTERED]", "username"=>"myUser", "user"=>{"username"=>"myUser", "email"=>"someemail#website.com"}}
It looks like you send slightly wrong parameters. To be recognized by Authlogic, password parameter should go under user key in parameters hash. I.e. that line from Rails log should look like this (pay attention to the end of string):
{"email"=>"someemail#website.com", "password"=>"[FILTERED]", "username"=>"myUser", "user"=>{"username"=>"myUser", "email"=>"someemail#website.com", "password" => "[FILTERED]"}}
To fix it, you can do a hack like this:
private
def user_params
params.require(:user).permit(:username, :email).merge(:password => :password)
end
Alternatively, you can adjust the parameters sent from the client side (for example, using user[password] parameter's name instead of just password when sending HTTP POST request).
try this out:-
acts_as_authentic do |config|
config.check_passwords_against_database = false
config.validate_password_field = false
config.crypted_password_field = false
end