Below is the versions that I am currently using:
The Ember side acts like the update was successful, but a new API request brings an unaltered user... Below is what Rails output:
22:07:18 web.1 | Processing by Api::V1::UsersController#update as JSON
22:07:18 web.1 | Parameters: {"user"=>{"full_name"=>"Sample User hghghfg", "display_name"=>"User#1", "password"=>"[FILTERED]", "email"=>"[email protected]", "date_of_birth"=>"2009-09-14T00:00:00.000Z", "gender"=>"male", "facebook_url"=>"", "twitter_url"=>"https://twitter.com/Deovandski", "personal_message"=>"sample personal message", "webpage_url"=>"www.google.com", "is_banned"=>false, "is_banned_date"=>nil, "legal_terms_read"=>true, "privacy_terms_read"=>true, "is_admin"=>true, "is_super_user"=>true, "sign_in_count"=>634, "last_sign_in_at"=>"2015-08-11T02:07:11.600Z", "updated_at"=>"2015-08-11T02:07:11.723Z", "created_at"=>"2015-08-10T03:16:28.314Z", "show_full_name"=>true}, "id"=>"2"}
22:07:18 web.1 | User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "[email protected]"]]
22:07:18 web.1 | (0.1ms) begin transaction
22:07:18 web.1 | SQL (0.2ms) UPDATE "users" SET "last_sign_in_at" = ?, "current_sign_in_at" = ?, "sign_in_count" = ?, "updated_at" = ? WHERE "users"."id" = ? [["last_sign_in_at", "2015-08-11 02:07:11.875566"], ["current_sign_in_at", "2015-08-11 02:07:18.560464"], ["sign_in_count", 636], ["updated_at", "2015-08-11 02:07:18.563145"], ["id", 2]]
22:07:18 web.1 | (22.1ms) commit transaction
22:07:18 web.1 | User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
22:07:18 web.1 | CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", "2"]]
22:07:18 web.1 | (0.1ms) begin transaction
22:07:18 web.1 | User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = '[email protected]' AND "users"."id" != 2) LIMIT 1
22:07:18 web.1 | User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE ("users"."display_name" = 'User#1' AND "users"."id" != 2) LIMIT 1
22:07:18 web.1 | (0.1ms) rollback transaction
22:07:18 web.1 | CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", "2"]]
22:07:18 web.1 | Completed 204 No Content in 60ms (ActiveRecord: 23.5ms)
As you can see, there is a rollback transaction in which I could not find why it happens (Check the answer below) or how to get more details out of it (The only information that I was able to get out of it was with Rails Logger, but the information was only the model with errors{} appended at the end). However, creating users is working fine and I do have a similar implementation for another model (posts) which is also working, so by natural deduction, I am leaning towards saying that Devise is the culprit. I did try to implement the non password user update from this blog post, but I still have the same issue.
The project is open source and it is available under Deovandski/Fakktion on github, but here are what I think the most important code snippets:
Rails Router
...
devise_for :users, controllers: {sessions: 'sessions'}
namespace :api do
namespace :v1 do
...
resources :users
...
Rails User_controller
...
def show
respond_with user
end
def create
respond_with :api, :v1, User.create(user_params)
end
def update
if user_params[:password].blank?
user_params.delete(:password)
user_params.delete(:password_confirmation)
end
successfully_updated = if needs_password?(user, user_params)
user.update(user_params)
else
user.update_without_password(user_params)
end
if successfully_updated
respond_with user, status: :ok
else
respond_with user.errors, status: :unprocessable_entity
end
end
...
private
def user
User.find(params[:id])
end
def needs_password?(user, params)
params[:password].present?
end
def user_params
params.require(:user).permit(:id, :show_full_name, :full_name, :display_name, :email, :date_of_birth, :gender, :facebook_url, :twitter_url, :personal_message, :webpage_url, :is_banned, :is_banned_date, :legal_terms_read, :privacy_terms_read, :is_admin, :is_super_user, :sign_in_count, :password, :number_of_comments, :number_of_posts, :last_sign_in_at, :reset_password_sent_at, :reset_password_token, :updated_at, :created_at)
end
Due to the lack of errors or any useful information, this bug hunt took a while and it turned out to end at the user model on the rails end. More specifically, the lack of these exactly two lines:
validates :password, length: {minimum: 8}, presence: true, on: :create
validates :password, length: {minimum: 8}, on: :update, allow_blank: true
On a sidenote, now the client can update their information with or without setting a new password (as long as they are authenticated.) My objective is to require the current password when the user tried to make changes, so let me know if you would like to see such implementation.