I created Devise Users table and Type table. I added the type_id column to the users table through migration.
Below are the links in home.html.erb:
<%= link_to 'Basic Sign up', new_user_registration_path(type: #basic_type), class: 'btn btn-success'%>
<%= link_to 'Pro Sign up', new_user_registration_path(type: #pro_type), class: 'button' %>
Below is the pages_controller.rb
class PagesController < ApplicationController
def home
#basic_type = Type.find(1)
#pro_type = Type.find(2)
end
def about
end
end
Below are the models:
type.rb
class Type < ActiveRecord::Base
has_many :users
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
belongs_to :type
end
This is my migration file of type:
class CreateTypes < ActiveRecord::Migration
def change
create_table :types do |t|
t.string :name
t.timestamps
end
end
end
This is the migration file adding types to user:
class AddTypeToUser < ActiveRecord::Migration
def change
add_column :users, :type_id, :integer
end
end
Users table in schema.rb:
create_table "users", force: :cascade do |t|
t.string "email", limit: 255, default: "", null: false
t.string "encrypted_password", limit: 255, default: "", null: false
t.string "reset_password_token", limit: 255
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", limit: 4, default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip", limit: 255
t.string "last_sign_in_ip", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "type_id", limit: 4
end
These are my registration forms:
_basic_form.html.erb:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {id: 'basic_type'}) do |f| %>
<%= devise_error_messages! %>
<%= hidden_field_tag 'type', params[:type] %>
<div class="field form-group">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password %>
<% if #validatable %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off", class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control' %>
</div>
<div class="actions form-group">
<%= f.submit "Sign up", class: 'btn btn-success' %>
</div>
<% end %>
_pro_form.html.erb:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= hidden_field_tag 'type', params[:type] %>
<div class="field form-group">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password %>
<% if #validatable %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off", class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control' %>
</div>
<div class="actions form-group">
<%= f.submit "Sign up", class: 'btn btn-success', id: 'form-submit-btn' %>
</div>
<% end %>
new.html.erb:
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<% if params[:type] == '2'%>
<h1>Pro Account</h1>
<p>Sign up for the pro account!</p>
<% else %>
<h1>Basic Account</h1>
<p>Sign up for free and get basic access to our community.</p>
<% end %>
</div>
<div class="col-md-6 col-md-offset-3">
<div class="well">
<h2>Sign up</h2>
<% if params[:type] == '2'%>
<%= render "pro_form"%>
<% else %>
<%= render "basic_form"%>
<% end %>
<div class="actions form-group btn btn-default">
<%= render "devise/shared/links" %>
</div>
</div>
</div>
</div>
When I am signing up as basic or as pro in URL it is showing:
http://localhost:3000/users/sign_up?type=1
OR
http://localhost:3000/users/sign_up?type=2
But in database in the type_id column it is showing as nil.
Related
So I have two models, User and Employee. User has one employee and Employee belongs to User. I want to create an employee but first I have to create a new User. My Employee model does not have the attributes :email, :password, :password_confirmation so I created virtual attributes. This is the error that pops up Validation failed: Email is invalid, Password confirmation doesn't match Password
here is my employee model
class Employee < ApplicationRecord
belongs_to :user
attr_accessor :email, :password, :password_confirmation
validates :email, format: { with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
validates :password, confirmation: true
end
my employee controller
class EmployeesController < ApplicationController
def create
#newuser=User.create!(
email: :email,
password: :password,
password_confirmation: :password_confirmation
)
#employee = Employee.new(employee_params)
respond_to do |format|
if #employee.save
format.html { redirect_to #employee, notice: 'Employee was successfully created.' }
format.json { render :show, status: :created, location: #employee }
else
format.html { render :new }
format.json { render json: #employee.errors, status: :unprocessable_entity }
end
end
end
private
def employee_params
params.require(:employee).permit(:name, :contact_no, :role_id, #newuser.id)
end
end
And my form
<%= form_for(employee) do |f| %>
<% if employee.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(employee.errors.count, "error") %> prohibited this employee from being saved:</h2>
<ul>
<% employee.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email %>
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.password_field :password %>
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :contact_no %>
<%= f.text_field :contact_no %>
</div>
<div class="field">
<%= f.label :role_id %>
<%= f.number_field :role_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I'm still learning rails and would greatly appreciate your help
if you don't have attributes :email, :password, :password_confirmation then remove the following validation:
validates :email, format: { with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
validates :password, confirmation: true
from Employee Model.
I have found the solution to my problem, it seems that my user parameters weren't following rails' strong parameters rule. so my controller has this now
def employee_params
params.require(:employee).permit(:name, :contact_no, :role_id)
end
def user_params
params.require(:employee).permit(:email, :password, :password_confirmation)
end
I was then able to make the user using the parameters without a problem.
I did make a attribute called address before . But I didn't use it in the sign up form . When I input all text field in sign up form , it flashes the error
The form contains 1 error.
Address can't be blank
Any other places I should check with ?
Controller
def new
#tutor = Tutor.new
end
def create
#tutor = Tutor.new(tutor_params)
if #tutor.save
log_in #tutor
flash[:success] = "Congratulations! Your registration is successful!"
redirect_to #tutor
else
render 'tutors/new'
end
end
# Handle sign-up failure, to redirect the tutor to the registeration form again
def tutor_params
params.require(:tutor).permit(:name, :email, :password, :password_confirmation,:gender
,:education_level,:institution,:exprience,:district,:subject,:student_level)
end
Sign Up page
<%= form_for(#tutor) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.label :gender %>
<%= f.select(:gender, ['Male', 'Female'] , class: 'form-control' )%>
<%= f.label :tutor_education_level %>
<%= f.select(:education_level, ['Bachelor', 'Master', 'Doctor'] , class: 'form-control' )%>
<%= f.label :tutor_institution %>
<%= f.text_field :institution, class: 'form-control' %>
<%= f.label :tutorial_experience %>
<%= f.text_field :experience, class: 'form-control' %>
<%= f.label :tutor_preferred_district %>
<%= f.text_field :district, class: 'form-control' %>
<%= f.label :tutor_preferred_subject %>
<%= f.text_field :subject, class: 'form-control' %>
<%= f.label :tutor_required_student_level %>
<%= f.select(:student_level, ['P1-P3', 'P4-P6', 'S1-S3', 'S4-S6'] , class: 'form-control' )%>
<%= f.submit "Create tutor's account", class: "btn btn-primary" %>
<% end %>
_error_messages.html.erb
<% if #tutor.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(#tutor.errors.count, "error") %>.
</div>
<ul>
<% #tutor.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
db/schema.rb(uupdate)
create_table "tutors", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "address"
t.string "remember_token"
t.string "gender"
t.string "education_level"
t.string "institution"
t.integer "experience"
t.string "district"
t.string "subject"
t.string "student_level"
end
add_index "tutors", ["email"], name: "index_tutors_on_email", unique: true
add_index "tutors", ["remember_token"], name: "index_tutors_on_remember_token"
end
tutor.rb (update2)
`class Tutor < ActiveRecord::Base
before_save {self.email = email.downcase}
before_save :create_remember_token
validates :name, presence: true, length: { maximum: 50}
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true
has_secure_password
validates :address, presence: true, length: {maximum: 100}
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
`
Change
validates :address, presence: true, length: {maximum: 100}
to
validates :address, length: {maximum: 100}
in your model tutor.rb
You are validating for the presence of address field in your model while creating a tutor, but you are not passing address params.
If you want to delete existing address field from db,
In your terminal, do
rails g migration remove_address_from_tutors
Add the following code in your newly created migration file
class RemoveAddressFromTutors < ActiveRecord::Migration
def change
remove_column :tutors, :address
end
end
and then do rake db:migrate in your terminal
def create
#tutor = Tutor.new(tutor_params)
if #tutor.save
log_in #tutor
flash[:success] = "Congratulations! Your registration is successful!"
redirect_to #tutor
else
flash[:tutor] = #tutor
redirect_to new_tutor_path
end
end
Also make sure your validates_presence_of :address in your tutor model.
I have a form that is going to be used, but i run into this problem when opening the form:
NoMethodError in Measures#new
Showing /home/supervisor/Rubyrails/Werkvergunning/app/views/measures/_form.html.erb where line #22 raised:
undefined method `measurement_type' for #<Measure:0x007f7bb3c5f978>
Did you mean? measurement
measurement?
measurement=
measurement_was
I am absolutely positive that the field exists and other fields from the same table used to work without problem, so it is just thos one field.
What is going on and how can i fix it?
The _form:
<%= form_for(#measure) do |f| %>
<% if #measure.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#measure.errors.count, "error") %> prohibited this measure from being saved:</h2>
<ul>
<% #measure.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :measurement %><br>
<%= f.text_field :measurement %>
</div>
<div class="field">
<%= f.label :type %><br>
<%# f.select :measurement_type, [['Product verklaring','product vrij verklaring'],['Elektrotechnische maatregel','Elektrotechnische maatregelen'],['Maatregel door vergunninghouder','maatregel door vergunninghouder'], ['brandpreventie', 'brandpreventie'], ['persoonnlijke bescherming', 'persoonlijke bescherming']] %>
<%= f.text_field :measurement_type %>
</div>
<div class="field">
<%= f.label :valid_from %><br>
<%= f.date_select :valid_from %>
</div>
<div class="field">
<%= f.label :valid_to %><br>
<%= f.date_select :valid_to %>
</div>
<div class="field">
<%= f.label :enquiry_measure_id %><br>
<%= f.text_field :enquiry_measure_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The table:
create_table "measures", force: :cascade do |t|
t.string "measurement", limit: 255
t.string "measurement_type", limit: 255
t.date "valid_from"
t.date "valid_to"
t.integer "enquiry_measure_id", limit: 4
end
Thanks
I have a Post model and Tag model with many to many relationships.
Post Model:
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
end
Tag model:
class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end
I also have a join table for posts_tags :
class JoinPostsAndTags < ActiveRecord::Migration
def change
create_table :posts_tags do |t|
t.integer :tag_id
t.integer :post_id
t.timestamps null: false
end
end
end
Now, I need to provide multiple selection for selecting tags for a post.
Below is the post form.html.erb
<%= form_for #post do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :Name %><br>
<%= f.text_field :Name %>
</div>
<div class="field">
<%= f.label :Email %><br>
<%= f.text_field :Email %>
</div>
<div class="field">
<%= f.label :Message %><br>
<%= f.text_area :Message %>
</div>
<% #tags= Tag.all %>
<% if #tags %>
<% #tags.each do |tag| %>
<div>
<%= check_box_tag "post[tag_ids][]", tag.id, #post.tags.include?(tag) %>
<%= tag.name %>
</div>
<% end %>
<% end %>
<br><br>
<%= link_to 'Create Tag', tags_path %>
<br><br>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
It is not adding the selected tags to the post. I need to add the selected tags to the post. How can I do it.
But, in rails console if I use post= Post.first tag= Tag.first post.tags<<tag it adds the tag to the post.
I don't have any special code in post controller to handle this. Please help me.
Add {tag_ids:[]} to your params permit arguments in your PostsController, like so:
def post_params
params.require(:post).permit(:name, :email, :message, {tag_ids:[]})
end
I am getting this error
1 error(s) on assignment of multiparameter attributes
And I am pretty sure it is from the date_selector.
Here is my model
class Order < ActiveRecord::Base
attr_accessor :card_type, :card_number, :card_verification,
:card_expires_on # I do not have these fields in my database
attr_accessible :cart_id, :card_expires_on, :card_type, :first_name,
:ip_address, :last_name,:card_number, :card_verification, :zip, :address,
:state, :city
def credit_card
#credit_card ||= ActiveMerchant::Billing::CreditCard.new(
:brand => card_type,
:number => card_number,
:verification_value => card_verification,
:month => card_expires_on.month,
:year => card_expires_on.year,
:first_name => first_name,
:last_name => last_name
)
end
end
And the part of the controller that is involved
def create
#user = current_user
#cart = current_cart
#order = #cart.build_order(params[:order]) # here is where the error is
#order.user_id = #user.id
#order.ip_address = request.remote_ip
...
end
Here is the cart Model
class Cart < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
has_one :order
belongs_to :user
def add_product(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(:product_id => product_id)
end
current_item
end
def total_price
line_items.to_a.sum { |item| item.total_price}
end
def total_price_in_cents
return Integer(total_price * 100)
end
end
And heres the order form that goes along with order.rb...Thank you again for the help!!!
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :address %>
<%= f.text_field :address %>
</div>
<div class="field">
<%= f.label :city %>
<%= f.text_field :city %>
</div>
<div class="field">
<%= f.label :state %>
<%= f.select :state, #order.us_states %>
</div>
<div class="field">
<%= f.label :zip %>
<%= f.text_field :zip %>
</div>
<div class ="field">
<%= f.label :card_type %> <br />
<%= f.select :card_type, [["Visa", "visa"], ["MasterCard", "master"], ["Discover", "discover"], ["American Express", "american_express"]] %>
</div>
<div class="field">
<%= f.label :card_number %><br />
<%= f.text_field :card_number %>
</div>
<div class="field">ry
<%= f.label :card_verification, "Card Verification (CVV)" %><br />
<%= f.text_field :card_verification %>
</div>
<div class="field">
<%= f.label :card_expires_on %><br />
<%= f.date_select :card_expires_on, :discard_day => true, :start_year => Date.today.year, :end_year => (Date.today.year+10), :add_month_numbers => true %>
</div>
<div class="actions">
<%= f.submit %>
</div>
Have you tried #order = #cart.orders.new(params[:order])?
In the case of a one-to-one relationship between an order and a cart, that would be:
#cart.order.new(params[:order])