[enter image description here][1]
I keep getting this error message and can not figure out why it is. I believe it is because #resturant is nil. But I do not understand why it is nil.
Is there anyway to 'print or console log' the response so I can see what the problem is
[1]: https://i.stack.imgur.com/sHUrz.png
Here is the model
class Resturant < ApplicationRecord
mount_uploader :image, ImageUploader
serialize :image, JSON # If you use SQLite, add this line
belongs_to :user, optional: true
validates :name, :description, :location, :resturant, :glutenfree, :vegan, presence: true
validates :description, length: {maximum: 1000, too_long: "%{count} characters is the maximum allowed"}
validates :title, length: {maximum: 140, too_long: "%{count} characters is the maximum allowed"}
end
here is the controller:
class Resturant < ApplicationRecord
mount_uploader :image, ImageUploader
serialize :image, JSON # If you use SQLite, add this line
belongs_to :user, optional: true
validates :name, :description, :location, :resturant, :glutenfree, :vegan, presence: true
validates :description, length: {maximum: 1000, too_long: "%{count} characters is the maximum allowed"}
validates :title, length: {maximum: 140, too_long: "%{count} characters is the maximum allowed"}
end
# GET /resturants/new
def new
#resturant = Resturant.new
end
# GET /resturants/1/edit
def edit
end
# POST /resturants or /resturants.json
def create
#resturants = Resturant.new(resturant_params)
respond_to do |format|
if #resturant.save
format.html { redirect_to resturant_url(#resturant), notice: "Resturant was successfully created." }
format.json { render :show, status: :created, location: #resturant }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #resturant.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /resturants/1 or /resturants/1.json
def update
respond_to do |format|
if #resturant.update(resturant_params)
format.html { redirect_to resturant_url(#resturant), notice: "Resturant was successfully updated." }
format.json { render :show, status: :ok, location: #resturant }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #resturant.errors, status: :unprocessable_entity }
end
end
end
# DELETE /resturants/1 or /resturants/1.json
def destroy
#resturant.destroy
respond_to do |format|
format.html { redirect_to resturants_url, notice: "Resturant was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_resturant
#resturant = Resturant.find(params[:id])
end
# Only allow a list of trusted parameters through.
def resturant_params
params.require(:resturant).permit(:name, :genre, :description, :location, :glutenfree, :vegan, :image, :resturant)
end
end
You have a typo. (It often takes a second set of fresh eyes to see these.)
You have accidentally pluralized resturant in your create action but then are using the singular later on.
You have:
#resturants = Resturant.new(resturant_params)
Change it to:
#resturant = Resturant.new(resturant_params)
(You are also misspelling "Restaurant" throughout your entire application. It is up to you if you'd like to fix that or not. I know I myself have trouble spelling that one for some silly reason.)
I am trying to set the gender validation depending on the penultimate digit of the PESEL number (if the digit is even, then the gender is 'female'). For now my Profile.rb look like that:
class Profile < ApplicationRecord
enum gender: %i[male female]
validates :first_name, presence: true, on: :update
validates :last_name, presence: true, on: :update
validates :gender, presence: true, on: :update
validates :pesel, presence: true, on: :update
validates :contact_number, presence: true, on: :update
validates :pesel, format: { with: /\A(\d{11})\z/ }, on: :update
validate :gender_correct?
def gender_correct?
return self.pesel.blank?
if self.pesel[-2].to_i % 2 != 0
pesel_gender = 'male'
else
pesel_gender = 'female'
end
if pesel_gender != self.gender
errors.add(:gender, t('activerecord.errors.models.profile.attributes.gender.wrong'))
end
end
Unfortunately it doesn't work. Other validations works fine.
EDIT:
My update action:
def update
#profile = Profile.find(params[:id])
respond_to do |format|
#profile.avatar.attach(params[:avatar]) if params[:avatar].present?
if #profile.errors.empty? && #profile.update(profile_params)
#profile.onboarded = true
#profile.save
#profile.fill_info!
#profile.assign_dispensary
format.html { redirect_to authenticated_root_path, notice: t('.update.success') }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render 'pages/info', alert: t('.update.error') }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
If i tried to update profile with blank first/last name, pesel, gender or contact number,then an error is displayed below text field.
Before update:
https://drive.google.com/file/d/1uS30WKLBFt5jcUUycI4CQblnEOpkrWEc/view?usp=sharing
After update:
https://drive.google.com/file/d/1HJqk-0opJdoZQ37CkPwscfL8Ohb19n6A/view?usp=sharing
I wanted to display error "PESEL does not match the set gender. Correct the PESEL number." under gender text field if PESEL gender doesn't match selected gender. Is that enough info? Or should I add something else?
In my case it is pre_member instead of user. Even when it fails validations (pre_member does not save), it remains within the if block, does not go the the else block.
validations
class PreClubList < ActiveRecord::Base
validates_presence_of :email, :enterprise, :member
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
validates :email, format: { with: VALID_EMAIL_REGEX }
validates :enterprise, length: { minimum: 3 }
end
So if a user puts in one character for enterprise it still follows what's in the if block but doesn't save it.
action
class PreClubListsController < ApplicationController
def create
#member = PreClubList.new(pre_club_list_params)
respond_to do |format|
if #member.save
format.html
format.js { render "create" }
else
format.html
format.js {"alert('form had following errors : #{#member.errors.full_messages});"}
end
end
end
private
def pre_club_list_params
params.require(:pre_club_list).permit(:email, :enterprise, :member)
end
end
I'm using rails 4.1, simple_form
I'm trying to update a user without having to provide a password, but approaches that worked on older devise/rails versions no longer work with devise 3 and rails 4 strong parameters.
I'm using my user_controller to update but I have also tried using a custom devise registration controller with devise_parameter_sanitizer, without success.
The form does not require a password (has no password field) and the user_controller handling the update looks like so:
# PATCH/PUT /users/1
def update
if user_params[:password].blank?
Rails.logger.info "entered if statement"
user_params.delete :password
user_params.delete :password_confirmation
Rails.logger.info(user_params.inspect)
end
#user = current_user
if #user.update(user_params)
redirect_to #user, notice: 'User was successfully updated.'
else
Rails.logger.info(#user.errors.inspect)
render action: 'edit'
end
end
private
def user_params
params.require(:user).permit(:screen_name, :full_name, :email, :about,
:location, :profile_pic, :password, :password_confirmation, :current_password)
end
.. the log after a submit looks like:
Started PATCH "/users/13" for 127.0.0.1 at 2013-05-29 11:18:18 +0100
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"20avah2OzaOVubAiam/SgvbYEQ4iijEWQqmNo7xD4rY=", "user"=>{"screen_name"=>"Darcbar", "full_name"=>"Barry Darcy", "about"=>"", "location"=>"", "website_url"=>"", "twitter_username"=>"", "email"=>"barry#gmail.com"}, "commit"=>"Save changes", "id"=>"13"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 13 ORDER BY "users"."id" ASC LIMIT 1
Entered if statement...
{"screen_name"=>"Darcbar", "full_name"=>"Barry Darcy", "email"=>"barry#gmail.com", "about"=>"", "location"=>"", "twitter_username"=>"", "website_url"=>""}
(0.2ms) BEGIN
User Exists (0.8ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'barry#gmail.com' AND "users"."id" != 13) LIMIT 1
(0.2ms) ROLLBACK
#<ActiveModel::Errors:0x007fedf45bb640 #base=#<User id: 13, username: "darcbar", full_name: "Barry Darcy", about: "", location: "", email: "barry#gmail.com", encrypted_password: "$2a$10$Mb4zsRPPqZ9CYz0zdLMBU.62NyIk/T8s6Zw/uRTwWov3...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 9, current_sign_in_at: "2013-05-28 17:51:20", last_sign_in_at: "2013-05-28 16:42:52", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", authentication_token: nil, created_at: "2013-05-27 14:03:41", updated_at: "2013-05-28 17:51:20", screen_name: "Darcbar", profile_pic_file_name: nil, profile_pic_content_type: nil, profile_pic_file_size: nil, profile_pic_updated_at: nil>,
#messages={:password=>["please enter a password with at least 5 characters", "please enter a password with at least 5 characters"]}>
Rendered users/edit.html.haml within layouts/application (3.0ms)
Rendered partials/head/_user_options.haml (1.8ms)
Completed 200 OK in 74ms (Views: 12.1ms | ActiveRecord: 1.7ms)
Does anyone know why the password errors are present?
The password validation is coming from the user model:
validates :password, presence: true
The solution is to only validate presence on create and allow_blank on update:
validates :password, presence: true, length: {minimum: 5, maximum: 120}, on: :create
validates :password, length: {minimum: 5, maximum: 120}, on: :update, allow_blank: true
As of 2014, you can simply override a protected method and do:
class RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
end
You can use #user.update_without_password(user_params) method to update your other fields.
For example, I have this in my custom users_controller.rb. I update with remote call (ajax).
#users_controller.rb
def update
respond_to do |format|
if needs_password?(#user, user_params)
if #user.update_with_password(user_params_password_update)
flash[:success] = 'User was successfully updated. Password was successfully updated'
format.js {render 'update'}
else
error = true
end
else
if #user.update_without_password(user_params)
flash[:success] = 'User was successfully updated.'
format.js {render 'update'}
else
error = true
end
end
if error
flash[:error] = #user.errors.full_messages.join(', ')
format.js {render json: #user.errors.full_messages, status: :unprocessable_entity}
end
end
end
private
def needs_password?(user, user_params)
!user_params[:password].blank?
end
def user_params
params[:user].permit(:email, :password, :password_confirmation, :username, :full_name)
end
#Need :current_password for password update
def user_params_password_update
params[:user].permit(:email, :password, :password_confirmation, :current_password, :username, :full_name)
end
The key is in this "user_params[:password].blank?". The next is a example of the code:
def update
if user_params[:password].blank?
params = user_params_without_password
else
params = user_params
end
respond_to do |format|
if #user.update(params)
format.html { redirect_to #user, notice: t(:user_update) }
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
private
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:email, :username, :first_name, :last_name, :admin, :locked, :password)
end
def user_params_without_password
params.require(:user).permit(:email, :username, :first_name, :last_name, :admin, :locked)
end
Hope you help
I went round in circles on this for ages. The answers are all in validatable as suggested by mrstif above. If you use the validatable module Devise works out of the box (with configuration options) allowing you to update user details without supplying a password so be very careful about rolling your own password validations.
simply override the Devise by creating app/controller/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
resource.update(params.except(:current_password))
end
end
this code will directly update user params except :current_password
and update config/routes.rb
devise_for :users, controllers: {registrations: 'registrations'}
My goal was to enable editing user attributes without requiring a password, unless it's changing email, password or deleting the account. And here's what worked for me:
app/controllers/registrations_controller.rb:
class RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters
...
def update
params[:user][:team_attributes][:id] = current_user.team.id
account_update_params = devise_parameter_sanitizer.sanitize(:account_update)
if password_required?
successfully_updated = resource.update_with_password(account_update_params)
else
account_update_params.delete(:current_password)
successfully_updated = resource.update_without_password(account_update_params)
end
if successfully_updated
sign_in resource, bypass: true
redirect_to '/'
else
render :edit
end
end
def destroy
current_password = devise_parameter_sanitizer.sanitize(:account_update)[:current_password]
resource.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
error_messages = 'Current password ' + resource.errors[:current_password].join
if resource.destroy_with_password(current_password)
redirect_to '/'
else
redirect_to delete_account_path, notice: error_messages
end
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:account_update) do |user_params|
user_params.permit(:username, :email, :password, :password_confirmation, :current_password, :name, :phone_number
end
end
private
def password_required?
(resource.email != params[:user][:email] if params[:user][:email].present?) || params[:user][:password].present?
end
end
Update config/routes.rb:
devise_for :users, controllers: { registrations: 'registrations' }
In views/devise/registrations/edit.html.haml
# edit form
...
= simple_nested_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { class: 'mo-form' }, defaults: { placeholder: false, hint: false }) do |f|
...
# delete form
...
= simple_form_for(resource, as: resource_name, url: user_registration_path(resource_name), method: :delete, html: { class: 'mo-form' }, defaults: { placeholder: false, hint: false }) do |f|
...
I made use in that case of the method update_columns.
It avoids having to bypass password validation for instance.
#user.update_columns(user_params)
However, this method will not modify the timestamp of the updated_at field and this also needs to be addressed, either by merging { updated_at: Time.current } or by a touch.
I know this is something you can't do inside of rails or aren't supposed to do but I need to somehow get the amount a user is inputing in a field of the form and use that value.
This is what my model looks like
class Deposit < ActiveRecord::Base
belongs_to :credit_card
belongs_to :user
validates :credit_card, presence: true
validates :user, presence: true
validates :tx_type, inclusion: %w(debit credit)
# validates :amount, presence: true, numericality: true
before_create :add_transaction_to_merchant
after_create :update_user_balance
attr_readonly :credit_card_id, :user_id, :fee_id, :tx_type, :status, :merchant_tx_id
attr_accessible :tx_type, :amount, :status, :merchant_tx_id, :credit_card_id,
:user_id, :user
def amount
return attributes[:amount] if attributes[:amount]
set_amount
end
def tx_type
attributes[:tx_type] || 'debit'
end
def send_receipt
Resque.enqueue(PaymentCompletedSender, self.id)
end
def update_user_balance
user_balance =user.balance + set_amount
user.balance = user_balance
user.save
end
private
def add_transaction_to_merchant
set_amount
return false if credit_card.nil?
return true unless amount > 0
result = Braintree::Transaction.sale(
amount: amount,
payment_method_token: credit_card.token,
options: { submit_for_settlement: true }
)
if result.success?
self.merchant_tx_id = result.transaction.id
# status will be authorized or submitted_for_settlement
self.status = result.transaction.status
else
errors.add(:base, result.message)
if result.transaction.nil?
# validation errors prevented transaction from being created
logger.error(result.errors)
else
self.merchant_tx_id = result.transaction.id
# status will be processor_declined, gateway_rejected, or failed
self.status = result.transaction.status
end
end
end
def set_amount
attributes[:amount]
end
end
The Controller:
# POST /deposits
# POST /deposits.json
def create
#deposit = Deposit.new(params[:deposit])
#deposit.user = current_user
#deposit.credit_card = current_user.credit_cards.try(:first)
binding.pry
respond_to do |format|
if #deposit.save
format.html { redirect_to "/", notice: 'Deposit was successfully created.' }
format.json { render json: #deposit, status: :created, location: #deposit }
else
format.html { render action: "new" }
format.json { render json: #deposit.errors, status: :unprocessable_entity }
end
end
end
This is what is params the form is sending
{"utf8"=>"✓",
"authenticity_token"=>"r0M0sRr7QO9kl0IWrJSgvj45DFrC6mbbuA+ttgEaUI0=",
"deposit"=>{"amount"=>"100"},
"commit"=>"Pay Now"}
Any thoughts on how to return the value of amount from the form in the model?
you are doing this right? #deposit = Deposit.new(params[:deposit]) if you remove the amount and set_amount method in the model, you should be able to just use amount or self.amount in the model so the following should be enough
def add_transaction_to_merchant
return false if credit_card.nil?
return true unless amount > 0
result = Braintree::Transaction.sale(
amount: amount,
payment_method_token: credit_card.token,
options: { submit_for_settlement: true }
)