I have a custom Devise form that I want to update my devise user with. But the from is not saving the changes.
Form:
.small-12.columns
.well
=form_tag(test_registration_path, method: 'PUT', id: "my-awesome-dropzone.dropzone") do
.row
.small-4.columns
%input#photo-dropzone{:name => "file", :type => "file"}/
.small-8.columns
.row
.small-12.columns
= label_tag :name
= text_field_tag :name
= submit_tag "Submit", class: "button button-green"
Log:
Started PUT "/tests" for 127.0.0.1 at 2014-10-06 11:48:04 -0700
Processing by Tests::Devise::RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"0R7keMt16tsIdjawQHE7yq15Ye6V/w5I4klAvs1WWLY=", "name"=>"testt", "commit"=>"Submit"}
Artist Load (0.4ms) SELECT "artists".* FROM "artists" WHERE "artists"."id" = 19 ORDER BY "artists"."id" ASC LIMIT 1
Artist Load (0.2ms) SELECT "artists".* FROM "artists" WHERE "artists"."id" = $1 LIMIT 1 [["id", 19]]
(0.1ms) BEGIN
(0.1ms) COMMIT
Redirected to http://site.dev/artists/19
Completed 302 Found in 5ms (ActiveRecord: 0.8ms)
RegistrationsController#Update
def update
# For Rails 4
account_update_params = devise_parameter_sanitizer.sanitize(:account_update)
# For Rails 3
# account_update_params = params[:user]
# required for settings form to submit when password is left blank
if account_update_params[:password].blank?
account_update_params.delete("password")
account_update_params.delete("password_confirmation")
end
#user = Test.find(current_test.id)
if #user.update_attributes(account_update_params)
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case their password changed
sign_in #user, :bypass => true
redirect_to artist_path(#user)
else
render "edit"
end
end
What do I have to do to properly update my params?
Did you point devise to your custom controller?
https://github.com/plataformatec/devise/wiki/How-To:-Customize-routes-to-user-registration-pages
Related
Here is the code I'm trying to use in my controller:
profiles_controller.rb:
class ProfilesController < ApplicationController
...
def update
respond_to do |format|
# assume valid data sent (I've already tested for this)
if #user.update(user_params)
# password_reset? check's parameter passed to action that a check box was
# checked (which enables/disables password/confirmation fields. If unchecked,
# fields are disabled and no password parameters are sent to this action.
# #user was set to current_user in a before_action already
# inspecting #user at this point returns the same thing as current_user here
sign_in(:user, #user) if password_reset?
# current_user is still set to #user and is valid
# after redirection current_user becomes nil
format.html {
redirect_to home_path, notice: 'Your profile was successfully updated.'
}
else
format.html { render :edit }
end
end
end
...
private
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
#user_params ||= params.require(:user).permit(:first_name, :last_name, :email, :phone, :password, :password_confirmation, :reset_password)
end
def password_reset?
#user_params["reset_password"] == "1"
end
end
application_controller.rb:
class ApplicationController < ActionController::Base
...
private
...
def require_user
logger.debug "IN REQUIRE_USER, CURRENT_USER IS: #{current_user.inspect}"
unless current_user
store_location
redirect_to new_user_session_url, notice: "That url doesn't exist."
return false
end
end
def require_admin
# this line will actually log a user in
#sign_in(:user, User.first) unless current_user
logger.debug "IN REQUIRE_ADMIN, CURRENT_USER IS: #{current_user.inspect}"
unless current_user && current_user.is_admin?
redirect_to(home_path, notice: "That url doesn't exist.") and return false
end
end
...
end
development.log:
Started PATCH "/profile" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by ProfilesController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"....", "user"=>{....}, "commit"=>"Update Profile"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:47
IN REQUIRE_USER, CURRENT_USER IS: #<User id: 1 ....>
(0.1ms) begin transaction
↳ app/controllers/profiles_controller.rb:16
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND "users"."id" != ? LIMIT ? [["email", "...."], ["id", 1], ["LIMIT", 1]]
↳ app/controllers/profiles_controller.rb:16
User Update (0.3ms) UPDATE "users" SET "encrypted_password" = ?, "updated_at" = ? WHERE "users"."id" = ? [["encrypted_password", "$2a$11...."], ["updated_at", "2019-05-28 17:38:45.346414"], ["id", 1]]
↳ app/controllers/profiles_controller.rb:16
(2.3ms) commit transaction
↳ app/controllers/profiles_controller.rb:16
PASSWORDS PASSED IN SO USER PASSWORD CHANGE OCCURRED
REDIRECTING TO HOME PATH
Redirected to http://localhost:3000/admin
Completed 302 Found in 121ms (ActiveRecord: 3.2ms)
Started GET "/admin" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by Admin::PagesController#index as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:65
IN REQUIRE_ADMIN, CURRENT_USER IS: nil
Redirected to http://localhost:3000/
Filter chain halted as :require_admin rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.2ms)
Started GET "/" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by PagesController#index as HTML
Rendering pages/index.html.erb within layouts/application
Rendered pages/index.html.erb within layouts/application (0.7ms)
Rendered application/_navigation.html.erb (1.7ms)
Rendered application/_alert.html.erb (0.3ms)
Completed 200 OK in 1152ms (Views: 1151.2ms | ActiveRecord: 0.0ms)
I've searched around and seen by_pass: true being passed to sign_in but that doesn't help. I've also tried #current_user = #user once I've signed the user in (#current_user is the direct instance variable for the Devise controller btw) and that does not help either.
Any ideas?
Devise ignores signin if the user is already signed in, try:
if #user.saved_change_to_encrypted_password? # for rails 5+, for previous - .encrypted_password_changed?
sign_in #user, force: true
end
You can signin new session if the user is already signed in.
Devise said
# Sign in a user bypassing the warden callbacks and stores the user
# straight in session. This option is useful in cases the user is
# signed in, but we want to refresh the credentials in session.
Please use like below one.
bypass_sign_in(#user)
I am having trouble inputting data into my new model.
I created a new model so I can assign Users to Affiliates.
I have a Users, Affiliates, and UserAffiliates model.
UserAffiliates:
belongs_to :users
belongs_to :affiliates
User:
has_and_belongs_to_many :user_affiliate
has_and_belongs_to_many :affiliate, through: :user_affiliate, optional: true
Affiliate:
has_many :user_affiliates
has_many :users, through: :user_affiliates
How it works, is an affiliate can have many users, but a user will ever only have one affiliate. I then have a commission column within the UserAffiliates table to set the commission based on a user by user basis.
I created this form, and it doesn't seem to be working (which is stemmed from a <% #users.each do |user| %> that goes through each user in a table:
<%= form_for user, remote: true do |f| %>
<% f.fields_for :user_affiliates, remote: true do |f| %>
<%= f.text_field :affiliate_id, class: "form-control" %>
<%= f.submit "Add Affiliate", data: {confirm: "Are you sure?"}, class: "btn btn-light" %>
<% end %>
<% end %>
I get this error:
Parameters: {"utf8"=>"✓", "user"=>{"user_affiliates"=>{"affiliate_id"=>"1"}}, "commit"=>"Add Affiliate", "id"=>"2"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
↳ app/controllers/users_controller.rb:58
Completed 500 Internal Server Error in 62ms (ActiveRecord: 6.4ms)
ArgumentError (wrong number of arguments (given 0, expected 1..2)):
app/controllers/users_controller.rb:88:in `[]'
app/controllers/users_controller.rb:88:in `user_params'
app/controllers/users_controller.rb:61:in `block in update'
app/controllers/users_controller.rb:60:in `update'
User controller params:
def user_params
params.require(:user).permit(:name, :approved, :seller, :buyer, :admin, :stripe_account, :email, :password, :password_confirmation, :role, :affiliate_id, :affiliate_ids [], :user_affiliates, :commission)
end
Is my form wrong?
I want to be able to list users in a table as a user.admin, have a text field, and enter an affiliate_id, and then have the user_id and affiliate_id inputted into the UserAffiliate table. I also want to be able to add commission rates that both the user.admin and Affiliate can change.
How can I do this correctly?
Update:
I fixed my params but still have errors:
params:
def user_params
params.require(:user).permit(:name, :approved, :seller, :buyer, :admin, :stripe_account, :email, :password, :password_confirmation, :role, :affiliate_id, :user_affiliates, :affiliate, :commission, affiliate_ids: [])
end
Error:
Started PATCH "/users/2" for 127.0.0.1 at 2019-01-10 21:20:53 -0500
Processing by UsersController#update as JS
Parameters: {"utf8"=>"✓", "user"=>{"user_affiliates"=>{"affiliate_id"=>"1"}}, "commit"=>"Add Affiliate", "id"=>"2"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
↳ app/controllers/users_controller.rb:58
Unpermitted parameter: :user_affiliates
(0.5ms) BEGIN
↳ app/controllers/users_controller.rb:61
(0.1ms) ROLLBACK
↳ app/controllers/users_controller.rb:61
Completed 406 Not Acceptable in 21ms (ActiveRecord: 5.3ms)
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/users_controller.rb:60:in `update'
I tried changing it to user_affiliate (non pluar) and plural in all the controller, model, and form. Is there anything i need to do to my update on the users controller?
User Controller update:
def update
#user = User.find(params[:id])
# #affiliate = current_affiliate
respond_to do |format|
if #user.update(user_params) # <- you'll need to define these somewhere as well
if #user.admin?
format.html { redirect_to '/admin/users', notice: "yahoo" }
format.json { render json: #user }
# elsif #affiliate
# format.html { redirect_to '/a/clients', notice: "yahoo" }
# format.json { render json: #user }
else
format.html { render :edit }
format.json { render json: { errors: #user.errors }, status: :unprocessable_entity }
end
end
end
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
Help me please. Rails swear...
What should I change? I allowed all parameters (permit_params), but this does not help:
ActiveModel::ForbiddenAttributesError
Extracted source (around line #17):
#user = User.where(id: params[:id]).first_or_create
#user.superadmin = params[:user][:superadmin]
#user.attributes = params[:user].delete_if do |k, v|
(k == "superadmin") ||
(["password", "password_confirmation"].include?(k) && v.empty? && !#user.new_record?)
end
"config.action_controller.permit_all_parameters = true" solves the problem. But I do not want to disable strong_parameters.
UPDATE
app/admin/user.rb
ActiveAdmin.register User do
form do |f|
f.inputs "User Details" do
f.input :email
f.input :password
f.input :password_confirmation
f.input :superadmin, :label => "Super Administrator"
end
f.actions
end
create_or_edit = Proc.new {
#user = User.where(id: params[:id]).first_or_create
#user.superadmin = params[:user][:superadmin]
#user.attributes = params[:user].delete_if do |k, v|
(k == "superadmin") ||
(["password", "password_confirmation"].include?(k) && v.empty? && !#user.new_record?)
end
if #user.save
redirect_to :action => :show, :id => #user.id
else
render active_admin_template((#user.new_record? ? 'new' : 'edit') + '.html.erb')
end
}
member_action :create, :method => :post, &create_or_edit
member_action :update, :method => :put, &create_or_edit
permit_params :authenticity_token, :commit, :id, user: [:email, :password, :password_confirmation, :superadmin]
end
P.S. I worked on this guide.
The problem is very similar to this problem: I get ActiveModel::ForbiddenAttributesError with Active Admin and Devise I get this error when I create a new user in the administration panel ActiveAdmin.
UPDATE1
console
Started POST "/admin/users" for 127.0.0.1 at 2017-12-08 22:57:04 +0300
Processing by Admin::UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"***********", "user"=>{"email"=>"test#test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "superadmin"=>"0"}, "commit"=>"Create User"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" IS NULL ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
(3.0ms) BEGIN
(0.4ms) ROLLBACK
Completed 500 Internal Server Error in 24ms (ActiveRecord: 5.2ms)
ActiveModel::ForbiddenAttributesError
ActiveModel::ForbiddenAttributesError):
app/admin/user.rb:17:in `block (2 levels) in <top (required)>'
I have to agree with the answer given to the question you referenced, per the doc please try:
permit_params :email, :password, :password_confirmation, :superadmin
Im having a weird issue trying to force my users to change their passwords on first login.
My server output is telling me it completed the patch successfully, however when I go to log back into the app its still the old password? I'll post output below.
But first here is my code to make this happen:
#application_controller.rb
# Force PW Change On 1st Login
def after_sign_in_path_for(resource)
if current_user.sign_in_count == 1
edit_passwords_path
else
authenticated_root_path
end
end
#passwords_controller.rb
def edit
#user = current_user
end
def update
if current_user.update_without_password(user_params)
flash[:notice] = "Password updated successfully."
redirect_to authenticated_root_path
else
flash[:alert] = "There was a problem, please try again."
render :edit
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
#passwords form_for
<%= form_for current_user, url: passwords_path do |f| %>
password:<br />
<%= f.password_field :password %><br />
password_confirmation:<br />
<%= f.password_field :password_confirmation %><br />
<br />
<%= f.submit %>
<% end %>
#routes.rb
resource :passwords
The force password is doing everything it is supposed to except actually saving the new passwords.
my server output:
Started PATCH "/passwords" for ::1 at 2016-09-07 02:23:43 -0600
Processing by PasswordsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"zUOrOdquBht6uwvjvBkPj2yaO0dCgL+3XGhKo0YV1+W/4rEEiiIRHwwOzRCqvSVeVkAO0M7c73ogcmgNQDq/DQ==", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update User"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.1ms) BEGIN
(0.1ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 5ms (ActiveRecord: 0.7ms)
Started GET "/" for ::1 at 2016-09-07 02:23:43 -0600
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Processing by WelcomeController#index as HTML
Rendering welcome/index.html.erb within layouts/application
Rendered welcome/index.html.erb within layouts/application (0.4ms)
Rendered layouts/navigation/_unassigned.html.erb (0.5ms)
Rendered layouts/messages/_flash_msg.html.erb (0.5ms)
Completed 200 OK in 56ms (Views: 54.9ms | ActiveRecord: 0.0ms)
In PasswordsController#Update change update_without_password to update_with_password:
def update
if current_user.update_with_password(user_params)
flash[:notice] = "Password updated successfully."
redirect_to authenticated_root_path
else
flash[:alert] = "There was a problem, please try again."
render :edit
end
end