Unable to pass params data to create a user - json

I have a rails app that accepts json request to create a user. A sign_up basically which is a GET. I can't create a user when i pass in this url http://localhost:3000/sign_up.json?username=chalam&email=holy#yahoo.com&name=chalami&password=chalami
I know I am passing the password in the open but that is not my concern here. i checked the logs and this is what i see
Started GET "/sign_up.json?username=chalam&email=holy#yahoo.com&name=chalami&password=[FILTERED]" for 127.0.0.1 at 2013-05-28 10:37:37 +0700
Processing by UsersController#create as JSON
Parameters: {"username"=>"chalam", "email"=>"holy#yahoo.com", "name"=>"chalami", "password"=>"[FILTERED]"}
(0.1ms) begin transaction
User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."username" IS NULL LIMIT 1
User Exists (0.0ms) SELECT 1 AS one FROM "users" WHERE "users"."email" IS NULL LIMIT 1
(0.0ms) rollback transaction
(0.0ms) begin transaction
CACHE (0.0ms) SELECT 1 AS one FROM "users" WHERE "users"."username" IS NULL LIMIT 1
CACHE (0.0ms) SELECT 1 AS one FROM "users" WHERE "users"."email" IS NULL LIMIT 1
(0.0ms) rollback transaction
Completed 200 OK in 6ms (Views: 0.1ms | ActiveRecord: 0.3ms)
As you can see although the parameter Parameters: {"username"=>"chalam", "email"=>"holy#yahoo.com", "name"=>"chalami", "password"=>"[FILTERED]"} clearly show that parameters are being passed, they are not being entered into the database CACHE (0.0ms) SELECT 1 AS one FROM "users" WHERE "users"."username" IS NULL LIMIT 1
CACHE (0.0ms) SELECT 1 AS one FROM "users" WHERE "users"."email" IS NULL LIMIT 1
Main problem is data from the params is not being "used" to create a User
One thing to note is I can create a user through the console in terminal. I will try to include all relevant information
rails version: 3.2.13 and
I am using thin instead of WEBBRICK
My user.rb
class User < ActiveRecord::Base
attr_accessible :email, :name, :username
attr_accessor :password
before_save :encrypt_password
validates_uniqueness_of :username, :email
validates_presence_of :password, :on => :create
validates_presence_of :email, :username
def encrypt_password
if password.present?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
def self.authenticate(username, password)
user = find_by_username(username)
if(user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt))
user
else
nil
end
end
end
My Controller
class UsersController < ApplicationController
respond_to :json
def new
#user = User.new
end
def create
#user = User.new(params[:user])
#user.save
if #user.save
respond_to do |format|
format.json { render :json => {:status => "200", :message => "Signed up successfully"}}
end
else
respond_to do |format|
puts #user.errors.inspect
format.json { render :json => {:status => "400", :message => "Failed"}}
end
end
end
def index
#user = User.all
render :json =>#user
end
end

Okay, so I have come up with a solution and I thought I should post it, it might help people
Problem: I could not create a user using a Json response although I could do it through rails console
Mistakes:
I created a GET route to create a User which compromises security
I added the password field to attr_accessor and not to attr_accessible
Solutions:
changed the action from GET to POST(in the routes.rb). To create a user(for a POST) I used curl. In my case my curl statement was
curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d ' {"user":{"name":"name","username":"username","email":"email#email.com","password":"app123"}}' http://localhost:3000/sign_up. Here is a useful post about curl
2.In my user model I included attr_accessor :password as well as attr_accessible :password

Related

Ruby on Rails. Can't create a record in database

Having a problem while creating a new record in database.
Model currently looks like this:
class User < ActiveRecord::Base
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
before_save {!self.email.downcase}
validates :name, presence: true, length: {maximum: 50}
validates :email, presence: true, length: {maximum: 255}, format: {with: VALID_EMAIL_REGEX}, uniqueness: {case_sensitive: false}
has_secure_password
validates :password, presence: true, length: {minimum: 6}
end
Initially tried to create a record from the code, but failed without any errors.
As a next step I tried to create a record manually in console, but still with the same result. No errors available. Skipping validations, reseting database, restarting server or excluding email REGEXP (always a source of troubles for me) from validations doesn't help...
user = User.new(name: "Fedor U", email: "fredy#mail.ru", password: "asdzxc123", password_confirmation: "asdzxc123")
=> #<User id: nil, name: "Fedor U", email: "fredy#mail.ru", created_at: nil, updated_at: nil, password_digest: "$2a$10$89SABxu2lOo3gj6DiqLZEOlSheAfEk0ex.5GYmJ5e8i...">
>> user.save
(0.2ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('fredy#mail.ru') LIMIT 1
(0.1ms) rollback transaction
=> false
>> user.errors.any?
=> false
user.errors.full_messages
=> []
>> user.save(validation: false)
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('fredy#mail.ru') LIMIT 1
(0.1ms) rollback transaction
=> false
Any ideas what am I doing wrong? Rails 4.2.0, bcrypt 3.1.7. Database is empty at the moment.
!self.email.downcase will return true or false
use self.email.downcase! to change the email into smallcase.

Dynamic aspects of Rails 4 app not working in production

I just deployed my first rails 4 app to a VPS and now I cannot write to the production database. Everything deployed fine (migrations etc) and I can log on the mysql database with sequel pro and see it is all there however when I try create a user using the app's new user form instead of notifying 'Thank you for registering' (as it does in development) it asks me to login to proceed. No record is created in the database.
I can see in the log that it is binding show rather than the users id to the :id parameter and therefore redirecting to login rather than creating a session. Why would this be?
This is the app log
I, [2014-08-09T00:33:45.753714 #31030] INFO -- : Started GET "/login" for xx.xxx.xxx.xx at 2014-08-09 00:33:45 +0200
I, [2014-08-09T00:33:45.755372 #31030] INFO -- : Processing by SessionsController#new as HTML
I, [2014-08-09T00:33:45.757942 #31030] INFO -- : Rendered sessions/new.html.erb within layouts/application (1.1ms)
I, [2014-08-09T00:33:45.758940 #31030] INFO -- : Completed 200 OK in 3ms (Views: 2.5ms | ActiveRecord: 0.0ms)
I, [2014-08-09T00:33:52.048559 #31030] INFO -- : Started POST "/sessions" for xx.xxx.xxx.xx at 2014-08-09 00:33:52 +0200
I, [2014-08-09T00:33:52.050765 #31030] INFO -- : Processing by SessionsController#create as HTML
I, [2014-08-09T00:33:52.050912 #31030] INFO -- : Parameters: {"utf8"=>"?^?^?", "authenticity_token"=>"xxxxxxxxxxxxxxxx", "email"=>"xxxx#gmail.com", "password"=>"[FILTERED]", "commit"=>"Log In"}
I, [2014-08-09T00:33:52.056027 #31030] INFO -- : Rendered sessions/new.html.erb within layouts/application (1.4ms)
I, [2014-08-09T00:33:52.057333 #31030] INFO -- : Completed 200 OK in 6ms (Views: 3.1ms | ActiveRecord: 0.7ms)
I, [2014-08-09T00:34:16.625949 #31030] INFO -- : Started GET "/users/show" for 92.225.136.50 at 2014-08-09 00:34:16 +0200
I, [2014-08-09T00:34:16.628217 #31030] INFO -- : Processing by UsersController#show as HTML
I, [2014-08-09T00:34:16.628359 #31030] INFO -- : Parameters: {"id"=>"show"}
I, [2014-08-09T00:34:16.630009 #31030] INFO -- : Redirected to http://xx.xxx.xxx.xx/
I, [2014-08-09T00:34:16.630207 #31030] INFO -- : Filter chain halted as :authorize rendered or redirected
I, [2014-08-09T00:34:16.630443 #31030] INFO -- : Completed 302 Found in 2ms (ActiveRecord: 0.0ms)
Edit 1: Here is my session controller:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to users_path, notice: "Logged In!"
else
flash.now[:error] = "Email or password is invalid. Please try again."
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged Out!"
end
end
And here is my users controller:
class UsersController < ApplicationController
before_action :authorize, except: [:new]
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
def update
respond_to do |format|
#user = User.find(params[:id])
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
def destroy
#user = User.find(params[:id])
if #user.present?
#user.destroy
end
redirect_to users_path, notice: "User successfully deleted."
end
def create
#user = User.new(params[:user].permit(:name, :surname, :title, :telefon, :email, :password, :password_confirmation, :salt, :encrypted_password))
if #user.save
session[:user_id] = #user.id
redirect_to root_url, notice: "Vielen Dank für Ihre Anmeldung"
else
render "new"
end
end
def index
#users = User.all
end
private
def user_params
params.require(:user).permit(:name, :surname, :title, :telefon, :email, :password, :password_confirmation, :salt, :encrypted_password)
end
end

Why are my json attributes bouncing off in POST in Sinatra?

I hope someone can share their knowledge with me. I have a small Sinatra app that I want to POST json data to it. The record is being created, thankfully, but none of the attributes make it. I've read several JSON examples using curl but they all yield the same result. So it makes me think it's my model. I can create records using tux fine so perhaps it's not my model.
curl command:
curl -XPOST -H "Content-Type: application/json"
"localhost:4567/date" -d
'{ "post": { "title": "different tile here"}}'
curl output:
=> {"id":13,"title":null,"body":null,"created_at":"2014-04-21T18:13:53Z",
"updated_at":"2014-04-21T18:13:53Z"}
sinatra output:
[2014-04-27T20:03:48.035710 #45360] DEBUG -- : (0.1ms) commit transaction
127.0.0.1 - - [27/Apr/2014 20:03:48] "POST /date HTTP/1.1" 200 - 0.0181
{"post":{"title":"different tile here"}}
D, [2014-04-27T20:09:32.614274 #45360] DEBUG -- : (0.1ms) begin transaction
D, [2014-04-27T20:09:32.615917 #45360] DEBUG -- : SQL (0.4ms) INSERT INTO "posts" ("created_at", "updated_at") VALUES (?, ?) [["created_at", 2014-04-28 01:09:32 UTC], ["updated_at", 2014-04-28 01:09:32 UTC]]
D, [2014-04-27T20:09:32.617656 #45360] DEBUG -- : (1.5ms) commit transaction
D, [2014-04-27T20:09:32.617852 #45360] DEBUG -- : (0.1ms) begin transaction
D, [2014-04-27T20:09:32.618132 #45360] DEBUG -- : (0.0ms) commit transaction
127.0.0.1 - - [27/Apr/2014 20:09:32] "POST /date HTTP/1.1" 200 - 0.0070
D, [2014-04-27T20:09:57.796909 #45360] DEBUG -- : Post Load (0.3ms) SELECT "posts".* FROM "posts" ORDER BY created_at DESC
127.0.0.1 - - [27/Apr/2014 20:09:57] "GET / HTTP/1.1" 200 2149 0.0128
app.rb
require 'sinatra'
require 'sinatra/activerecord'
require './environments'
require 'sinatra/flash'
require 'sinatra/redirect_with_flash'
require 'json'
class Post < ActiveRecord::Base
end
post "/posts" do
#post = Post.new(params[:post])
if #post.save
redirect "posts/#{#post.id}"
else
erb :"posts/create"
end
end
post '/date', :provides => 'json' do
data = JSON.parse(request.body.read)
json_data = data.to_json
content_type :json
##post = Post.new(params)
#post = Post.create(
title: data[:title]
body: data[:body]
)
if #post.save
#post.to_json
else
halt 500
end
end
get "/posts/create" do
#title = "Create post"
#post = Post.new
erb :"posts/create"
end
get "/posts/:id" do
#post = Post.find(params[:id])
#title = #post.title
erb :"posts/view"
end
get "/" do
#posts = Post.order("created_at DESC")
#title = "Welcome."
erb :"posts/index"
end
Gemfile
source 'https://rubygems.org'
ruby "2.0.0"
gem "sinatra"
gem 'activerecord', '4.0.4'
gem "sinatra-activerecord"
gem 'sinatra-flash'
gem 'sinatra-redirect-with-flash'
gem 'json'
group :development do
gem 'sqlite3'
gem "tux"
end
group :production do
gem 'pg'
end
environments.rb
configure :development do
set :database, 'sqlite3:///dev.db'
set :show_exceptions, true
end
configure :production do
db = URI.parse(ENV['DATABASE_URL'] || 'postgres:///localhost/mydb')
ActiveRecord::Base.establish_connection(
adapter: db.scheme == 'postgres' ? 'postgresql' : db.scheme,
host: db.host,
username: db.user,
password: db.password,
database: db.path[1..-1],
encoding: 'utf9'
)
end
I've left off my layout files since I'm testing this POST via this rudimentary API. I've bounced around the few examples of Sinatra API's on the web and don't know what I'm not seeing. What am I overlooking here? It's almost like Strong Parameters in Rails 4, but if so why does tux allow me to create records? thanx, sam

cURL post to server resulting in a UnknownFormat error

I am very new at rails and having a hard time doing a cURL post to my server. Any help would be apreciated.
I am posting JSON data to my server.
this is my curl post curl -X POST -H "Content-Type: application/json" -d '[{"photo":[{ "location": "location", "userID": "userid" },{ "location": "location", "userID": "userid" },{"location": "location", "userID": "userid"}]}]' http://localhost:3000/photo/create
this is my controller:
class SendphotoController < ApplicationController
def create
#photo = Photo.new(:photo => params[:location], :photo => params[:userID])
respond_to do |format|
if #photo.save
puts "Done"
else
puts "NOPE"
end
end
end
I get the error of ActionController::UnknownFormat (ActionController::UnknownFormat):
This is the full log:
Started POST "/photo/create" for 127.0.0.1 at 2013-09-08 22:03:56 -0400
Processing by SendphotoController#create as */*
Parameters: {"_json"=>[{"photo"=>[{"location"=>"location", "userID"=>"userid"}, {"location"=>"location", "userID"=>"userid"}, {"location"=>"location", "userID"=>"userid"}]}], "sendphoto"=>{"_json"=>[{"photo"=>[{"location"=>"location", "userID"=>"userid"}, {"location"=>"location", "userID"=>"userid"}, {"location"=>"location", "userID"=>"userid"}]}]}}
WARNING: Can't mass-assign protected attributes for Photo: photo
app/controllers/sendphoto_controller.rb:4:in `create'
(0.0ms) begin transaction
SQL (0.3ms) INSERT INTO "photos" ("created_at", "updated_at") VALUES (?, ?) [["created_at", Mon, 09 Sep 2013 02:03:56 UTC +00:00], ["updated_at", Mon, 09 Sep 2013 02:03:56 UTC +00:00]]
(215.8ms) commit transaction
Done
Completed 406 Not Acceptable in 235ms
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/sendphoto_controller.rb:5:in `create'
You're using a respond_to block, but not any formats. Your block should look something like this:
respond_to do |format|
format.html {
# respond to a web form with HTML
}
format.json {
# respond to API request
}
end
If you just want a generic response for all formats, you can drop the respond_to bit altogether. But puts isn't going to work in a Controller context (or pretty much anywhere in Rails for that matter); you have to render something.
That might look something like this
def create
if Photo.create # ...
render text: "done"
else
render text: "nope"
end
end

mysql keeps pulling select email NULL for session in RoR

I tried using Devise but since that didn't work out for me, I decided to build the authentication and sessions from scratch. I realize the problem wasn't devise, but it's mysql. For some reason, when I register a user, the information and attributes are stored in the database. When I login using the email and password, it keeps telling me that it's an invalid email/password. The log looks like this:
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"NFudGruZS79uwDrKzbHDQrBjlcwQ7AkC958vI4aHDAs=", "session"=>{"email"=>"first#abc.com", "password"=>"[FILTERED]"}, "commit"=>"Sign in"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`email` IS NULL LIMIT 1
After some investigation, I know it's not because I didn't install mysql or other gems properly because a brand new app works just fine.
Does anyone know why it's not pulling the email I entered and pulling email is NULL instead?
Should I just create a new database and switch my database.yml file to the new database instead?
Thanks in advance.
EDIT - SOME MORE CODE
user model:
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :email, :secondary_email, :password, :password_confirmation, :gender
has_many :user_owner_relationships
has_many :owners, :through => :user_owner_relationships
has_many :cash_endowments
has_many :checks, :through => :cash_endowments
has_many :owners, :through => :cash_endowments
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, :presence => true,
:uniqueness => { :case_sensitive => false },
:format => { :with => email_regex }
validates :name, :presence => true,
:length => { :maximum => 40 }
validates :password, :presence => true,
:confirmation => true,
:length => { :within => 6..20 }
sessions_controller (user controller is standard)
def new
#title = "Sign in"
end
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_path, :notice => "Welcome '#{user.first_name}"
else
flash.now.alert = "Invalid email or password."
render "new"
end
end
Rookie mistake -
It's actually because my new.html.erb for the sessions controller was not pulling the :session symbol from this code:
<%= form_for (:session, :url => sessions_path) do |f| %>
So I just ended up using form_tag instead.