NoMethodError raised following Railscast #250 - ruby-on-rails

I'm following the 'Authentication from scratch' railscast but cannot get it to work.
Controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to products_path, notice: 'User created successfully'
else
render 'new'
end
end
end
Model:
class User < ActiveRecord::Base
has_secure_password
attr_accessible :email, :password, :password_confirmation
validates_uniqueness_of :email
end
users#new form:
<h1>Sign up form</h1>
<%= form_for #user do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit %>
<% end %>
When I try to go to the new user form it throws up a NoMethodError - undefined method 'email' referring to the line that has 'f.text_field :email'.
What am I missing here?
Thanks any help appreciated.

Your users table does not have an email column. Please run a migration to add the column to your users table.

Related

Form data not getting saved to database

I'm new to RoR and I'm trying to create a sign-up form. When I click on 'Create my account', data does not get saved to the database. I have added resources: users to my routes file. Is there something else I'm missing?
This is my view (signup.html.erb)
Sign Up
<%= form_for #user, :url => { :action => "create" } do |f| %>
<%= f.label :emp_id,"Employee ID" %><br>
<%= f.text_field :emp_id, class: 'form-control' %><br><br>
<%= f.label :password, "Password" %><br>
<%= f.password_field :password, class: 'form-control' %><br><br>
<%= f.label :password_confirmation, "Password Confirmation" %><br>
<%= f.password_field :password_confirmation, class: 'form-control' %><br><br>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
This is my controller
class UsersController < ApplicationController
def new
#user = User.new
end
def signup
#user = User.new
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(user_params)
if #user.save
render 'login'
else
render 'signup'
end
end
def user_params
params.require(:user).permit(:emp_id, :password)
end
end
You need to permit :password_confirmation
def user_params
params.require(:user).permit(:emp_id, :password, :password_confirmation)
end
And make sure there are no other validations like email presence or that will cause validations to fail

Rails map one field in form to two fields in model

I've seen a lot of posts about how to map 2 form fields to one model field, but what about mapping 1 form field to provide answers for two (or more) model fields? I have a form for users which gives a field, last_name, for a user. But I want the default password for that user to also be last_name (and I have password_confirmation set up, so that also needs to be last_name). How would I do this?
Form:
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name, class: 'form-control' %>
<%= f.label :last_name %>
<%= f.text_field :last_name, :password, :password_confirmation,
class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.hidden_field :access_level, :value => "Chair" %>
<%= f.label :Phone %>
<%= f.text_field :phone_number, :id => "phone", class: 'form-control' %>
<p> </p>
<div class="col-md-12">
<%= f.submit "Add Chair", class: "btn btn-primary" %>
</div>
<% end %>
</div>
</div>
user_controller.rb
def create
#user = User.new(user_params)
if #user.save
log_in #user
current_user
flash[:success] = "Welcome to the Penn Model Congress!"
redirect_to after_sign_in_path
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password,
:password_confirmation, :access_level,
:phone_number)
end
end
I would add a before_validation callback to the User model like this:
# in app/models/user.rb
before_validation :set_default_password
private
def set_default_password
self.password ||= last_name
self.password_confirmation ||= last_name
end
If this will be your default and you don't want the user to be able to override it on creation, you could set it on the controller:
View:
<%= f.text_field :last_name, class: 'form-control' %>
Controller:
def create
#user = User.new(user_params)
#user.password = #user.last_name
#user.password_confirmation = #user.last_name
if #user.save
log_in #user
current_user
flash[:success] = "Welcome to the Penn Model Congress!"
redirect_to after_sign_in_path
else
render 'new'
end
end

Ruby on Rails login form, always returns error can't be blank

I'm trying to setup a user sign-up system, and when I input an email and password, After pressing submit I always get the same errors: password can't be black, email can't be blank. I am a ruby newbie and have a hard time wrapping my head around parameters setting. If anyone can spot what I did wrong and point it out please do so. I would also be grateful for any documentation and explanations on what I did wrong.
I'm using rails 4.2.1 and ruby 2.2.1p85
Thanks
my controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user_params])
if #user.save
redirect_to root_url, :notice => "Signed up!"
else
render "new"
end
end
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
my new.html.erb:
<h1>Sign Up</h1>
<%= form_for #user do |f| %>
<%if #user.errors.any? %>
<div class="error_messages">
<h2>From is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</p>
<p class="button"><%= f.submit %></p>
<% end %>
my model(user.rb)
class User < ActiveRecord::Base
attr_accessor :password
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password
validates_presence_of :email
validates_uniqueness_of :email
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
end
You need to use user_params correctly. params[:user_params] will return nil.
Your create action should looks like:
def create
#user = User.new(user_params)
...
...
end
params[:user_params] is nil, use #user = User.new(user_params) instead

sign up and create new object at the same time

i'm new in Ruby on Rails.
I was trying to register a new user with devise and at the same time, create a new Company object. The association between them : User belongs to Company. Company has many users. I tried to make it based on this link : http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast, but it didnt work. it said : "undefined method for Company", which is Company doesnt have email attribute.
and in sign up form, i only put email attribute for user
<div class="title"><%= t('.signup') %></div>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="control-group"><%= f.label :email, t('.email') %>
<%= f.email_field :email %></div>
<div class="control-group"><%= f.label :password, t('.password') %>
<%= f.password_field :password %></div>
<div class="control-group"><%= f.label :password_confirmation, t('.password_confirmation') %>
<%= f.password_field :password_confirmation %></div>
<%= f.fields_for :company_attributes do |f_company| %>
<div class="control-group"><%= f_company.label :name, t('.company_name') %>
<%= f_company.text_field :name %></div>
<% end %>
<div class="buttons"><%= f.submit t('.signup'), class:"btn btn-primary" %><br>
<%= render "links" %></div>
<% end %>
updated
Company controller :
class CompaniesController < Devise::RegistrationsController
def new
#company = Company.new
#user = #company.users.build
end
def create
#company = Company.new(params[:company])
#user = User.create(params[:user].merge(company_id:company.id))
if #company.save
redirect_to "/"
else
render 'users/sign_up'
end
end
end
User Controller :
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to users_path
else
render 'users/new'
end
end
I would really appreciate any idea and any help. Thanks in advance
In your case, since you are only interested in receiving the company_name I'd simplify it and submit the company_name via a text_field_tag.
In other words, I would replace:
<%= f.fields_for :company_attributes do |f_company| %>
<div class="control-group"><%= f_company.label :name, t('.company_name') %>
<%= f_company.text_field :name %></div>
<% end %>
With this
<%= text_field_tag 'company_name', {placeholder:"Enter here the name of your company",class:"form-control"} %>
This would submit the name to the UsersController, and you could access it with params[:company_name] so the controller would look like this:
Users controller:
def new
#user = User.new
end
def create
#user = User.create(params[:user])
#Create a company via 'user<->company' association using 'company_name'
#company= #user.company.create(name: params[:company_name])
if #user.save
redirect_to users_path
else
render 'users/new'
end
end

Rails 4.0 Nested forms / data not saved

I have following code trying to create a new User with an associated new Shop resource. However, while the user data is saved correctly, no record for the shop is created. What is wrong?
Users controller:
class UsersController < ApplicationController
def new
#user = User.new
#user.shops.build
end
def create
#user = User.new(user_params)
if #user.save
flash[:success] = "Signed up successfully."
redirect_to root_path
else
flash[:danger] = "Signup failed!"
render 'new'
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation,
shop_attributes: [:name])
end
end
User model:
class User < ActiveRecord::Base
has_many :shops
accepts_nested_attributes_for :shops
end
Shop model:
class Shop < ActiveRecord::Base
belongs_to :user
end
Form:
<%= form_for(#user) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.fields_for :shop do |shop| %>
<%= shop.label :name %>
<%= shop.text_field :name %>
<% end %>
<%= f.submit "Create my account" %>
<% end %>
Check your singular/plural wording (shop_attributes, f.fields_for :shop):
def user_params
params.require(:user).permit(:email, :password, :password_confirmation,
shops_attributes: [:name])
end
and:
<%= f.fields_for :shops do |shop| %>

Resources