Ruby on Rails - Failed to create new user: Validation failed - ruby-on-rails

On creating a new user using postman, I'm getting the following error:
Failed to create new user: Validation failed: First name can't be blank, Email can't be blank, Email is invalid; Params: {:email=>nil, :first_name=>nil, :last_name=>nil, :plan=>"Basic", :role=>"requester_readonly", :phone_number=>nil, :ip=>nil, :company_name=>nil, :product_id=>2, :user_reference_id=>nil, :handle=>nil}
Error on postman:
{
"error": [
"First name can't be blank",
"Email can't be blank",
"Email is invalid"
],
"status": 400
}
I am passing the following values to params in postman:
{
"email": "customer#yahoo.com",
"firstName": "Demo",
"lastName": "Customer",
"password": "Password_0",
"phoneNumber": "0123456789",
"ip": "10.10.2.125",
"company": "xyz"
}
This is the function for user registration:
def register
product_id = $product_id
if params[:plan]
#plan = AppCommon::Plan.where(name: params[:plan], product_id: product_id).first
end
#plan = #plan || AppCommon::Plan.find_default(product_id)
form_params = {email: params[:email], first_name: params[:firstName], last_name: params[:lastName], password: params[:password], plan: #plan.name, role: 'requester_readonly', phone_number: params[:phoneNumber], ip: params[:ip], company_name: params[:company], product_id: product_id, user_reference_id: params[:referenceId]}
service = Web::UserCreater.new(form_params)
result = service.perform
#user = service.user
if result.success?
render json: {status: 200, authentication_token: #user.authentication_token}
else
error_response(#user.errors.full_messages.to_a)
end
end

probably the ruby on rails controllers are wrapping the params under a name https://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html
you can either turn it off by setting wrap_parameters false on the top of your controller but I do not advise on this!
you could probably print/log the entire params to see how they look like and probably permit them
pull form_params into its own method require the param wrapper then permit what you need
def form_params
params.require(:user).permit(:email, :first_name, :last_name, :password, :phone_number, :ip, :company_name, :user_reference_id)
end
then in your method get these params then merge the defaults:
user_creater_attributes = form_params.merge(product_id: product_id, plan: #plan.name, role: 'requester_readonly')

Related

Rails 5.1.: strong params for JSON POST request

I have JS where data are posted with Ajax and in terminal my params look like this:
Started POST "/strongbolt/user_groups" for 10.0.2.2 at 2017-06-27 16:27:23 +0000
Processing by Strongbolt::UserGroupsController#create as JSON
Parameters: {"strongbolt_user_group"=>{"name"=>"Some test group",
"description"=>"Some test description", "user_ids"=>{"0"=>{"id"=>"3"},
"1"=>{"id"=>"2"}, "2"=>{"id"=>"5"}}, "role_ids"=>{"0"=>{"id"=>"1"},
"1"=>{"id"=>"2"}}}}
My Create action looks like this:
def create
user_roles #Helper method
#user_group = Strongbolt::UserGroup.create!(user_group_params)
respond_to do |format|
format.js { flash.now[:notice] = "User group #{#user_group.name} created!" }
format.json { render json: {
data: #user_group.as_json(only: [:id, :name, :description], include: {
users: { only: [:id, :name] }, roles: {only: [:id, :name] }}),
}
}
end
end
private
def user_group_params
params.require(:strongbolt_user_group)
.permit(:name, :description, {user_ids: []}, {role_ids: []})
end
In my terminal I can see it create name and description, but does not insert user_ids and role_ids. So far I've been trying differently with params, but no luck - can't make them to be saved.
I get this error: Unpermitted parameters: :user_ids, :role_ids
How do I make all params to be saved, please? Thank you!
instead of
{
"strongbolt_user_group"=>{
"name"=>"Some test group",
"description"=>"Some test description",
"user_ids"=>{"0"=>{"id"=>"3"}, "1"=>{"id"=>"2"}, "2"=>{"id"=>"5"}},
"role_ids"=>{"0"=>{"id"=>"1"}, "1"=>{"id"=>"2"}}
}
}
you should send
{
"strongbolt_user_group"=>{
"name"=>"Some test group",
"description"=>"Some test description",
"user_ids"=>["3", "2", "5"],
"role_ids"=>["1", "2"]
}
}
EDIT
If you can't change the format of received params, you could do something like the following:
private
def user_group_params
modified_params.require(:strongbolt_user_group)
.permit(:name, :description, {user_ids: []}, {role_ids: []})
end
def modified_params
user_ids = params[:strongbolt_user_group][:user_ids].values.map(&:values).flatten
role_ids = params[:strongbolt_user_group][:role_ids].values.map(&:values).flatten
ActionController::Parameters.new({
strongbolt_user_group: params[:strongbolt_user_group].except(:user_ids, role_ids).merge(user_ids: user_ids, role_ids: role_ids)
})
end

How to save an image in mysql database unsing ROR json API call for mobile application development?

My json API is below
and I am using careerwave gem
{
"districtcity_id": 23,
"logo": "/home/amulyatanksale/Desktop/the_hulk.jpg",
"last_name": "Legend",
"regionstate_id": 33,
"name": "John",
"role_id": 10,
"email": "jwsohny#gmail.com",
"password": "12345678",
"password_confirmation": "12345678",
"address": "cape town",
"firstplanid": 12,
"contactno": "7897875887",
"is_auction_notification": true
}
And it shows the following error
No such file or directory # rb_sysopen - /home/amulyatanksale/Desktop/the_hulk.jpg
But if run the same API on my local machine it is working
Below is the code for call
def create_user
begin
Rails.logger.info "---------------ERROR WHILE REGISTER------#{params[:logo]}, #{params[:logo].split("/").last}"
parse_image_data(params[:logo], params[:logo].split("/").last)
#user = User.new(register_user_params)
#user.save
Rails.logger.info "---------------ERROR WHILE REGISTER------#{#user.to_json}"
#subscribeplan = Subscription.create(user_id: #user.id, planid: params[:plan_id], name: params[:sub_name], description: params[:description], price: params[:price], is_free: params[:is_free], totalpartscount: params[:totalpartscount] , startdate: Date.today, enddate: Date.today + 1.months)
#subscribeplan.save
#plan_id = #user.subscriptions.first.planid rescue nil
user_type = #user.role.nil? ? "" : #user.role.name
user_state = #user.regionstate.nil? ? "" : #user.regionstate.name
user_city = #user.districtcity.nil? ? "" : #user.districtcity.name
render status: 200, json: { result: :success, message: "Buyer Created.", first_name: #user.name, last_name: #user.last_name, email: #user.email, password: #user.password, logo: #user.logo, phone_no: #user.contactno, address: #user.address, user_type: user_type, registration_date: #user.created_at.to_date, state: user_state, city:user_city, email_auction_notification: #user.is_auction_notification, approval_status: #user.is_approved, user_id: #user.id, subscription_plan: #plan_id }
rescue Exception => e
Rails.logger.info "---------------ERROR WHILE REGISTER------#{#user.to_json}"
Rails.logger.info "---------------ERROR WHILE REGISTER------#{e.to_json}"
render status: 400, json: {errors: #user.errors.messages}, status: :unprocessable_entity
end
end
def parse_image_data(base64_image, img_name)
if img_name
begin
uploaded_file = ActionDispatch::Http::UploadedFile.new({
:tempfile => File.new(Rails.root.join(base64_image)),
:filename => img_name,
:type => Mime::Type.lookup_by_extension(File.extname(img_name)[1..-1]).to_s
})
rescue Exception => e
end
params[:register_user][:logo] = uploaded_file
end
You are passing the path to the file so that is because it works in your local only. You need to submit the form as "multipart/form-data
http://guides.rubyonrails.org/form_helpers.html#uploading-files

Undefined method 'permit' for "89718":String

I'm writing a simple Rails api that connects to a legacy SQL Server database. I am testing my REST actions for my contacts controller. When using FactoryGirl to create test objects, I ran into the error message mentioned in the title. My index and show actions work fine, but the create action is throwing this error. The relevant parts of my contacts_controller look like this:
def create
contact = Contact.new(contact_params)
if contact.save
render json: contact, status: 201, location: [:api, contact]
else
render json: { errors: contact.errors }, status: 422
end
end
...
private
def contact_params
params.require(:contact).permit(:name, :address_1, :city, :zip_code_5, :country)
end
And here is the relevant test code:
describe "POST #create" do
context "when is successfully created" do
before(:each) do
#user = FactoryGirl.create :user
#contact = FactoryGirl.create :contact
post :create, { contact: #contact }
end
it "renders the json representation for the contact record just created" do
contact_response = json_response
expect(contact_response[:name]).to eq #contact_attributes[:name]
end
it { should respond_with 201 }
end
end
The model:
class Contact < ActiveRecord::Base
belongs_to :user
validates :name, :address_1, :city, :zip_code_5, :country, :createddate, presence: true
end
The serializer (using the active_model_serializer gem):
class ContactSerializer < ActiveModel::Serializer
belongs_to :user
attributes :id, :name, :address_1, :city, :zip_code_5, :country
end
Things I've tried include:
Changing the 'belongs_to' to 'has_one' in the serializer (no change)
Removing the 'zip_code_5' from the permite...require line (strangely, I still got the error message about this property, perhaps because of the serializer?)
Removing the serializer (no change)
Any thoughts? I'm happy to provide any more necessary information.
EDIT
The value of #contact when it's passed to the create action:
#<Contact id: 89815, user_id: "d67b0d57-8f7f-4854-95b5-f07105741fa8", title: nil, firstname: nil, lastname: nil, name: "Alene Stark", company: nil, address_1: "72885 Bauch Island", address_2: nil, address_3: nil, city: "Joestad", state: nil, zip_code_5: "98117", zip_code_4: nil, country: "MF", status_id: 1, createddate: "2015-10-23 07:00:00", lastmodifieddate: "2012-11-29 08:00:00", errorreasonid: nil, computergenerated: true, sandbox: true, emailsubject: nil, jobtitle: nil, mergevar1: nil, mergevar2: nil, mergevar3: nil, mergevar4: nil, mergevar5: nil, mergevar6: nil, mergevar7: nil, mergevar8: nil, mergevar9: nil, mergevar10: nil, clientid: 1, isshared: true>
The value of params[:contact] at runtime:
{"city"=>"Seattle", "state"=>"WA", "zip_code_5"=>"98117", "country"=>"US"}
I also have my wrap parameters set to :json format, if that's relevant.
I used the console to recreate what my test was doing. I discovered that Contact was being passed as a string, instead of a hash. After a little Googling, I passed the #contact object as #contact.attributes, which passes a hash of the object. This solved the 'permit' problem, thanks for pointing me in the right direction.

Issue with apipie gem and rspec in rails 4

i'm writing the code to get my Rspec tests to pass on my api. I'm using the apipie gem to generate documentation and it seems that my tests are failing because thy are expecting a number and it's funny because this is exactly what I want to test.
The page fails when the :bpm parameter is not a number. is there any way of going around this ?
context "when is not created" do
before(:each) do
user = FactoryGirl.create :user
#invalid_lesson_attributes = { title: "California Dreamin",
bpm: "Hello"
}
request.headers['Authorization'] = user.auth_token
post :create, { user_id: user.id, lesson: #invalid_lesson_attributes }
end
it "renders an errors json" do
lesson_response = json_response
expect(lesson_response).to have_key(:errors)
end
it "renders the json errors on why the user could not be created" do
lesson_response = json_response
expect(lesson_response[:errors][:bpm]).to include "is not a number"
end
it { should respond_with 422 }
end
end
Update spec:
context "when is not updated" do
before(:each) do
patch :update, { user_id: #user.id, id: #lesson.id,
lesson: { bpm: "ten" }, format: :json }
end
it "renders an errors json" do
lesson_response = json_response
expect(lesson_response).to have_key(:errors)
end
it "renders the json errors on why the user could not be updated" do
lesson_response = json_response
expect(lesson_response[:errors][:bpm]).to include "is not a number"
end
it { should respond_with 422 }
end
in my users_controller:
api :POST, '/teachers/:user_id/lessons/', "Create lesson"
param :lesson, Hash, desc: 'Lesson information', :required => true do
param :title, String, desc: 'Title of the lesson', :required => true
param :bpm, :number, desc: 'tempo of the lesson (beats per second)', :required => true
end
error :code => 422, :desc => "Unprocessable Entity"
my error when I run my rspec tests :
Apipie::ParamInvalid: Invalid parameter 'bpm' value "Hello": Must be a number.
Adds format json to post request
post :create, { user_id: user.id, lesson: #invalid_lesson_attributes, format: :json }
That worked for me.

Ruby JSON API and post request with Postman

I'm using postman to make post request to my rails/grape API
Here is the json object
{
"customer":{
"first_name":"Joe",
"last_name":"Doe",
"email":"test#test.com",
"phone":"999-999-9999",
"addresses_attributes":[{
"address":{
"address1":"123 somewhere st",
"customer_id":"",
"address2":"",
"city":"Moldor",
"state":"CA",
"zip":"99999",
"region_id":"1"
}
}]
}
}
If send this to a api/v1/customers.json
I get the following error message
"error": "first_name is missing, last_name is missing, email is missing, phone is missing",
If I change the JSON format to:
{
"first_name":"Joe",
"last_name":"Doe",
"email":"test#test.com",
"phone":"999-999-9999",
"addresses_attributes":[{
"address":{
"address1":"123 somewhere st",
"customer_id":"",
"address2":"",
"city":"Moldor",
"state":"CA",
"zip":"99999",
"region_id":"1"
}
}]
}
I does creates the customer but it does not creates the address
In my Models I have
#customer.br
has_many :addresses
accepts_nested_attributes_for :addresses, allow_destroy: true
#address.rb
belongs_to :customer
Here is the api/vi/curtomer.rb
desc "Create a Customer"
params do
requires :first_name, type: String, desc: "First Name"
requires :last_name, type: String, desc: "Last Name"
requires :email, type: String, desc: "Email"
requires :phone, type: String, desc: "Phone"
optional :notes, type: String, desc: "Notes"
end
post do
# Tried with new instead of create
# test = Customer.new({
# first_name: params[:first_name],
# last_name: params[:last_name],
# email: params[:email],
# phone: params[:phone],
# notes: params[:notes],
# addresses_attributes: params[:addresses]
# })
Customer.create({
first_name: params[:first_name],
last_name: params[:last_name],
email: params[:email],
phone: params[:phone],
notes: params[:notes]
# addresses_attributes: params[:addresses]
})
end
The address looks pretty much the same as the customers
I'm not using controllers per Grapes Documentation
EDIT: to add customer.rb create code
Think your json data should be:
{ "customer":
{
"first_name":"Joe",
"last_name":"Doe",
"email":"test#test.com",
"phone":"999-999-9999",
"addresses_attributes":[{
"address1":"123 somewhere st",
"customer_id":"",
"address2":"",
"city":"Moldor",
"state":"CA",
"zip":"99999",
"region_id":"1"
}]
}
}
Refer to this example.
If it not works, show your controller code.

Resources