While applying logging concept to my book catalog display, when a user is regestering I am coming acorss this sort of error.
Can't mass-assign protected attributes: password_confirmation, password
And my code in app/model/user.rb is as follows:
class User < ActiveRecord::Base
attr_accessible :name, :password_digest
validates :name, :presence => true, :uniqueness => true
has_secure_password
end
And my code of create method in app/contollers/user_controller.rb
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to users_url, :notice => 'User #{#user.name} was successfully created.' }
format.json { render :json => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
Any help please!
If you want to assign those values in the way you're doing it, you need to add them to the attr_accessible in your model:
attr_accessible :name, :password_digest, :password, :password_confirmation
I suspect you may not want to assign both of those, so you might want to delete them from that hash first (in the controller):
user = params[:user]
user.delete(:password_confirmation)
#user = User.new(user)
You could also create a new hash containing just the values you want to use to create the new User, if you have only a few values to keep but a lot of values to ignore.
(You could also create a new "empty" User and just assign the values you want - if that makes more sense in your situation.)
Related
I'm using Mongodb in my Rails app. I have 2 models, which are Account and User. Account has many users and users belongs to account.
Account model
has_many :users, :inverse_of => :account, :dependent => :destroy
validates :organization_name, presence: true, uniqueness: true
User model
belongs_to :account, :inverse_of => :users
validates :account, :presence => false
validates :email, presence: true
has_secure_password
validates :password, length: { minimum: 6 }, allow_nil: true
def User.new_token
SecureRandom.urlsafe_base64
end
def self.create_with_password(attr={})
generated_password = attr[:email] + User.new_token
self.create!(attr.merge(password: generated_password, password_confirmation: generated_password))
end
User controller
def new
#user = User.find_by(params[:id])
#user = #current_user.account.users.new
end
def create
#user = User.find_by(params[:id])
#user = #current_user.account.users.create_with_password(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
format.js
else
format.html { render 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
format.js { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:id, :email, :password, :password_confirmation, :owner, :admin)
end
I can successfully sign up an account with a user. But when I tried to add a new user, the user record can't be saved. I assigned a password for users when creating a new user.
The error messages:
message: Validation of User failed. summary: The following errors were found: Account can't be blank resolution: Try persisting the document with valid data or remove the validations.
If I removed the self.create_with_password and manually type in the password in the form, it works. So i guess the error must be in the self create password, it seems like doesn't save the record. By the way I'm using Rails 5.0. Any idea to solve this?
Hey #ternggio Welcome to community.
Account can't be blank.
This error appear due to belongs_to statement in user.rb.
In rails > 5 belongs_to is by default required, You can set as optional with marking optional: true.
belongs_to :account, :inverse_of => :users, optional: true
and remove below line.
validates :account, :presence => false
Hope, this will help you.
I am new to Rails and I have these checkboxes that display the options just fine, but aren't changing anything in the database as the form is submitted.
The form in views has the following piece of code:
<%= form_for(#sector) do |f| %>
<%= f.collection_check_boxes :admins_id, Admin.all, :id, :name %>
<% end %>
and this is the corresponding action in the sectors controller:
def update
#sector = Sector.find(params[:id])
#sector.admins_id = params[:admins_id]
respond_to do |format|
if #sector.update(sector_params)
format.html { redirect_to #sector, notice: 'Sector was successfully updated.' }
format.json { render :show, status: :ok, location: #sector }
else
format.html { render :edit }
format.json { render json: #sector.errors, status: :unprocessable_entity }
end
end
end
private
def sector_params
params.require(:sector).permit(:title, :admins_id)
end
And, finally, I have these relations in the models:
class Sector < ActiveRecord::Base
has_many :admins, dependent: :destroy
validates :title, presence: true
validates :title, uniqueness: true
end
class Admin < ActiveRecord::Base
belongs_to :sector
end
Also, I can create and assign admins just fine in the rails console.
If you are setting a single admins_id then you don't need check boxes (which will pass through an array of ids) use collection_radio_buttons (for a single id) instead.
However, if you want to set multiple admins through the has_many association, then keep the checkboxes, but change the attribute name to be admin_ids. (Don't forget to change the name in the permit() whitelist as well).
Also, you can remove this line:
#sector.admins_id = params[:admins_id]
It's not necessary because it is set through the update().
In my Rails app, update_attribute seems not working. I'm trying to update a boolean field called billed. The same command works great for two other tables.
Output of rails console:
>> Expense.find(28).update_attributes(:billed => true)
=> false
>> Expense.find(28).billed
=> false
expenses_controller.rb:
# PUT /expenses/1
# PUT /expenses/1.json
def update
#expense = Expense.find(params[:id])
respond_to do |format|
if #expense.update_attributes(params[:expense])
format.html { redirect_to #expense, notice: 'Expense was successfully updated.' }
format.json { render json: #expense }
else
format.html { render action: "edit" }
format.json { render json: #expense.errors, status: :unprocessable_entity }
end
end
end
Expenses has these validations:
validates_presence_of :employee_id # Declare a required field
validates_presence_of :unitcost # Declare a required field
validates_presence_of :quantity # Declare a required field
validates_presence_of :exp_date # Declare a required field
validates_presence_of :category_id # Declare a required field
validates_presence_of :description # Declare a required field
validates_presence_of :markup # Declare a required field
validates :markup, :format => { :with => /^\d{3}$/}, :numericality => {:greater_than => 0}
validates :unitcost, :format => { :with => /\A\d+(?:\.\d{0,2})?\z/}, :numericality => {:greater_than => 0}
validates_numericality_of :quantity, :only_integer => true, :message => "Can only be whole number."
Thanks for the help!
Use update_attribute instead of update_attributes to update single column.
From the API
update_attribute
Updates a single attribute and saves the record without going through
the normal validation procedure. This is especially useful for boolean
flags on existing records. The regular update_attribute method in Base
is replaced with this when the validations module is mixed in, which
it is by default
Expense.find(28).update_attribute(:billed => true)
Please reference this question: same question or another similar question
I cannot seem to get my work scaffold to include the image URL from paperclip to JSON. I need this url to do some ajax manipulation to the dom.
To my understanding you add a def in a model and then you add a extra line to the format.json in the controller.
when I add the #work.avatar_url to my controller method def create it throws up a syntax error
syntax error, unexpected ',', expecting tASSOC
I'm really new to rails and MVC. All the answers make it sound so easy. Unfortunately, I'm just guessing and checking...
Controller Link: works_controller.rb
My Def Create
def create
#work = Work.new(params[:work])
respond_to do |format|
if #work.save
format.html { redirect_to #work, notice: 'Work was successfully created.' }
format.json { render json: #work, status: :created, location: #work }
else
format.html { render action: "new" }
format.json { render json: #work.errors, status: :unprocessable_entity }
end
end
end
Git Link Model: work.rb
class Work < ActiveRecord::Base
validates :name, :presence => true
has_many :categoryworks
has_many :categories, :through => :categoryworks
accepts_nested_attributes_for :categories
attr_accessible :name, :subtitle, :category_ids, :svg, :post_a, :post_b, :post_c, :post_d, :avatar
has_attached_file :avatar, :styles => { :medium => "1280x700>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
def avatar_url
avatar.url(:medium)
end
end
Try
format.json { render json: #work.as_json(:methods => [:avatar_url]), status: :created, location: #work }
instead of what you have used.
Here is my unaltered controller:
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
And here are my routes:
root :to => "songs#index"
match '/votes/:song_id/:user_id' => "votes#create"
resources :votes
resource :session
resources :users
resources :songs
match '/login' => "sessions#new", :as => "login"
match '/logout' => "sessions#destroy", :as => "logout"
And the error:
undefined method `user' for #<User:0x00000102b42a00>
Application Trace | Framework Trace | Full Trace
app/controllers/users_controller.rb:46:in `block in create'
app/controllers/users_controller.rb:45:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"oOzmpsbEJtnHC4YGeAf4N6pVxfK+Zf4W9ec+0E/Eds0=",
"user"=>{"email"=>"bhjjhb#hui.com",
"password"=>"[FILTERED]"},
"commit"=>"Create User"}
model:
class User < ActiveRecord::Base
attr_accessible :email, :password
validates_uniqueness_of :user
validates_presence_of :password
has_many :votes
end
http://guides.rubyonrails.org/active_record_validations_callbacks.html#uniqueness
This helper validates that the attribute’s value is unique
Your problem is in your validations; validates_uniqueness_of checks the uniqueness of a model attribute, so validates_uniqueness_of :user is trying to check that the user's user attribute is unique. In the process, it calls #user.user, which produces the NoMethodError.
Edited to add: As #Amar says, the way to fix this is by validating the uniqueness of some attribute or set of attributes that will be unique for each user record (such as :email).
instead of validates_uniqueness_of :user use this validates_uniqueness_of :email
validation mainly works on attribute