Error adding value names to devise - ruby-on-rails

Im getting an error trying to add the value name to devise, I think all did all things to make it work, but it doesnt work.
NoMethodError in Devise/registrations#new
undefined method `name' for #<User:0x00000002e4e038>
Here is my user model:
class User < ActiveRecord::Base
include Gravtastic
gravtastic :size => 165, :filetype => :png, :rating => 'R'
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
validates :email, :username, :presence => true, :uniqueness => true
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :username, :email, :password, :password_confirmation, :remember_me
has_many :topics, :dependent => :destroy
has_many :posts, :dependent => :destroy
def admin?
true if self.username == 'admin'
end
end
Here is my registration view:
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<p><%= f.label :name %><br />
<%= f.text_field :name %></p>
<p><%= f.label :email %><br />
<%= f.email_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><%= f.submit "Sign up" %></p>
<% end %>
<%= render :partial => "devise/shared/links" %>
And here is my devise registration view:
div class="module" style="padding:15px 25px 0px 25px;">
<div style="float:right; width:100%; padding-left:30px; border-left:1px solid #e2e2e2;">
<%= form_for("user", :as => resource_name, :url => registration_path("user")) do |f| %>
<%= devise_error_messages! %>
<p>
Nome: <br />
<%= f.text_field :name, :style => "font-size:2.0em", :autocomplete => "off" %><br />
</p>
<p>
Usuario: <br />
<%= f.text_field :username, :style => "font-size:2.0em", :autocomplete => "off" %><br />
</p>
<p>
Email: (apenas emails #usp.br sao aceitos) <br />
<%= f.text_field :email, :style => "font-size:2.0em", :autocomplete => "off" %><br />
</p>
<p>
Senha:<br />
<%= f.password_field :password, :style => "font-size:2.0em", :autocomplete => "off" %><br />
</p>
<p>
Confirmar senha:<br />
<%= f.password_field :password_confirmation, :style => "font-size:2.0em", :autocomplete => "off" %><br />
</p>
<p><%= f.submit "Criar" %></p>
<% end %>
</div>
<div class="clear"></div>
</div>
I already tryied rake db:migrate but it still doesnt solve my problem. Sorry, Im still a noob on rails.
EDIT:
Here is my migration file:
class DeviseCreateUsers < ActiveRecord::Migration
def self.up
create_table(:users) do |t|
t.database_authenticatable :null => false
t.recoverable
t.rememberable
t.trackable
t.confirmable
# t.encryptable
# t.confirmable
# t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both
# t.token_authenticatable
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
def self.down
drop_table :users
end
end
EDIT 2:
Here is my schema.rb
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20131121000236) do
create_table "categories", :force => true do |t|
t.string "title"
t.boolean "state", :default => true
t.integer "position", :default => 0
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "forums", :force => true do |t|
t.string "title"
t.text "description"
t.boolean "state", :default => true
t.integer "topics_count", :default => 0
t.integer "posts_count", :default => 0
t.integer "position", :default => 0
t.integer "category_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "posts", :force => true do |t|
t.text "body"
t.integer "forum_id"
t.integer "topic_id"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "topics", :force => true do |t|
t.string "title"
t.integer "hits", :default => 0
t.boolean "sticky", :default => false
t.boolean "locked", :default => false
t.integer "posts_count"
t.integer "forum_id"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :limit => 128, :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", :default => 0
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "topics_count", :default => 0
t.integer "posts_count", :default => 0
t.string "username"
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
end

At least from that migration file, it seems like you are missing name column for users table.
Add the name column for users table.
rails g migration AddNameToUsers
class AddNameToUsers < ActiveRecord::Migration
def change
add_column :users, :name, :string
end
end
Run rake migrate.
Restart server just to be safe.
FINAL Edit. NEver again!!
In the devise migration file, uncomment
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
rake db:drop db:create db:migrate
restart server

Related

Rails update not saving values

Please help me. I've been tearing out my hair trying to figure out what I feel should be a simple thing.
My update function "succeeds" but it does not actually save the new values. The console log doesn't throw an error, but it does say "Unpermitted parameter: profiles"
edit.html.erb
<div class="col-md-7 col-md-offset-3 main">
<% provide(:title, "Edit user")%>
<center><h1>Update your profile</h1></center>
<%= form_for(#person) do |f| %>
<%= render 'shared/error_messages' %>
<div class="col-md-12">
<%= render 'layouts/profilefields', f: f %>
<%= f.submit "Save Changes", class: "btn btn-large btn-primary" %>
</div>
<% end %>
</div>
_profilefields.html.erb
<%= f.fields_for :profiles do |prf|%>
<!--
<% if !#profileInfo["avatar"].blank? %>
<%= image_tag #contactInfo.avatar_url(:medium).to_s, :class=>"profilePhoto" %>
<% end %>
<div class="photoPreview">
<i class="fa fa-upload photoUpload"></i>
<p id="uploadClick">Click to Upload</p>
</div>
<%= prf.file_field :avatar, accept: 'image/png,image/gif,image/jpeg, image/jpg', id: 'uploadAvatar' %>
<p class="deletePhoto">Delete</p>
-->
<%= prf.label :about %>
<%= prf.text_field :about, :class => "form-control" %>
<%= prf.label :why %>
<%= prf.text_field :why, :class => "form-control" %>
<%= prf.label :goals %>
<%= prf.text_field :goals, :class => "form-control" %>
<%= prf.hidden_field :traveler_id, value: current_traveler.id %>
<% end %>
travelers_controller.rb
class TravelersController < ApplicationController
def edit
#person = Traveler.find(params[:id])
#profileInfo = Profile.find_or_initialize_by(traveler_id: params[:id])
##profileInfo[:email] = current_traveler.email
#This builds the form
#person.build_profile(#profileInfo.attributes)
end
def show
end
def update
#trav = Traveler.find(params[:id])
#prof = Profile.find_or_create_by(traveler_id: current_traveler.id)
if #trav.update(update_traveler_params)
flash[:success] = "Profile updated"
redirect_to feed_path
else # Failed. Re-render the page as unsucessful
render :edit
end
end
private
def update_traveler_params
params.require(:traveler).permit(:id, profiles_attributes: [:id, :first_name, :last_name, :about, :why, :goals,
:avatar, :traveler_id])
end
end
and the models
class Profile < ApplicationRecord
belongs_to :traveler, foreign_key: "traveler_id"
end
class Traveler < ApplicationRecord
# Include default devise modules. Others available are:
# , :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile
accepts_nested_attributes_for :profile, update_only: true, allow_destroy: true
end
and the schema. Is the profile foreignkey set up correctly?
ActiveRecord::Schema.define(version: 20160825224710) do
create_table "profiles", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "first_name"
t.string "last_name"
t.text "about", limit: 65535
t.text "why", limit: 65535
t.text "goals", limit: 65535
t.string "avatar"
t.integer "traveler_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["traveler_id"], name: "index_profiles_on_traveler_id", using: :btree
end
create_table "travelers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
end
end
I believe the problem is caused by your use of "profiles", when your association is actually a has_one.
Try changing:
profiles_attributes to profile_attributes in travellers_controller#update_traveler_params
:profiles to :profile in _profilefields.html.erb

How to use polymorphic user model with devise authentication on Ruby on Rails

I'm developing an application using devise , which has more than one type of user and each type has different data fields . For this, I am trying to use the idea applied here: http://blog.jeffsaracco.com/ruby-on-rails-polymorphic-user-model-with-devise-authentication.
My situation is exactly like this blog. I want to have only a login screen, but having more than one user table ( one for each type ), not to get a table with several empty fields.
The problem is that I tried to implement exactly the same as example and in my case is not working.
My models:
class User < ActiveRecord::Base
belongs_to :type, :polymorphic => true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
class Patient < ActiveRecord::Base
has_one :user, :as => :type
end
i'll put just this two models, because the others its the same for a while.
Controllers:
class PatientsController < ApplicationController
def create
#user = User.new(params[:user])
#patient = Patient.new(patient_params)
#user.type = #patient
if #patient.save
#user.save
redirect_to #patient
else
render 'new'
end
end
My view:
<%= form_for #patient, :url => patients_path(#patient), :html => {:method => :post} do |f| %>
<%= f.label :name, "Nome" %><br>
<%= f.text_field :name, placeholder:"Digite o nome do Paciente", required:"", autofocus: true %>
<br>
<%= f.fields_for :user do |u| %>
<%= u.label :email %><br />
<%= u.email_field :email %>
<%= u.label :password %>
<%= u.password_field :password, autocomplete: "off" %>
<%= u.label :password_confirmation %><br />
<%= u.password_field :password_confirmation, autocomplete: "off" %>
<% end %>
<%= f.submit "Ok" %>
<% end %>
My migrations:
class CreatePatients < ActiveRecord::Migration
def change
create_table :patients do |t|
t.string :name
t.timestamps null: false
end
end
end
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
end
end
And the error i'm getting is:
ActiveModel::MissingAttributeError in PatientsController#create can't
write unknown attribute type_id
I'm sorry for this huge post, but I did not want my doubt stay confused because I am researching this for some time and have found many related things , but nothing that would solve the problem.
Thanks for reading.

Pass a foreign table in a "form_for"

I have two model
user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :personal
before_create :generate_profile
end
and personal.rb
class Personal < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
end
and in my controller i have :
def createinfo
#user = current_user
#personal = #user.personal
end
I want to do a form for like that :
<%= form_for #personal do |f| %>
Trigramme : <%= f.text_field :trigramme, :input_html => { :value => 'blabla' } %><br />
Nom : <%= f.text_field :nom %><br />
Prenom : <%= f.text_field :prenom %><br />
Poste : <%= f.text_field :poste %><br />
Bio : <%= f.text_area :bio %><br />
<%= f.submit %>
<% end %>
But i have an error and I don't know how to resove that. I think the path current_user.personal is not accepted by form_for although it print the correct thing when I only put current_user.personal.trigramme in the code.
undefined method `personal_path' for #<#<Class:0x8e15a28>:0x8e15308>
do you know how can I do this form?
EDIT : My route.rb
Rails.application.routes.draw do
devise_for :users
root 'static_pages#cvpage'
get 'home' => 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'cvpage' => 'static_pages#cvpage'
get 'createinfo' => 'static_pages#createinfo'
end
EDIT 2 schema.rb :
create_table "personals", force: :cascade do |t|
t.string "trigramme"
t.string "nom"
t.string "prenom"
t.string "poste"
t.text "bio"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "personals", ["user_id"], name: "index_personals_on_user_id"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
YEAHH! I solve my problem (take a lot of time)
I put in my personal controller this :
def update
#user = current_user
#personal = #user.personal
if #personal.update_attributes(personal_params)
# if update is successful
else
# if update is unsuccessful
end
redirect_to home_path
end
def personal_params
params.require(:personal).permit(:trigramme, :nom, :prenom, :poste, :bio)
end
And i put in my view this form :
<%= form_for(#personal, html: { method: :put }) do |f| %>
Trigramme : <%= f.text_field :trigramme %><br />
Nom : <%= f.text_field :nom %><br />
Prenom : <%= f.text_field :prenom %><br />
Poste : <%= f.text_field :poste %><br />
Bio : <%= f.text_area :bio %><br />
<%= f.submit %>
Thank you to all of you !!

How to refer to a symbols' active record relationship inside a fields_for

Inside a fields_for block how can i reference the value of a relationship field.
For instance:
app/models/cart.rb
class Cart < ActiveRecord::Base
attr_accessible :lineitems_attributes
has_many :lineitems, dependent: :destroy
accepts_nested_attributes_for :lineitems
def total_price
lineitems.to_a.sum { |item| item.total_price }
end
end
app/models/lineitem.rb
class Lineitem < ActiveRecord::Base
attr_accessible :cart_id, :quantity, :package_id, :part_id
belongs_to :cart
belongs_to :package
belongs_to :part
def total_price
if package_id?
return package.price * quantity
end
if part_id?
return part.price * quantity
end
end
end
app/models/package.rb
class Package < ActiveRecord::Base
attr_accessible :description, :img_src, :name, :price
has_many :lineitems
end
app/views/cart/_form.html.erb
<%= form_for #cart do |f| %>
<%= c.fields_for :lineitems do |i| %>
<%= render 'lineitem_fields', :f => i %>
<% end %>
<%= c.submit %>
<% end %>
app/views/cart/_lineitem_fields.html.erb
<%= f.text_field :quantity %>
<% if :package_id? %>
<%= f.text_field :package_id %>
<% else %>
<%= f.text_field :part_id %>
<% end %>
<%= link_to 'Remove',
lineitem_path(:id),
:method => :delete,
:confirm => t('.confirm', :default => t("helpers.links.confirm",
:default => 'Are you sure?')) %>
relative pieces of schema
create_table "carts", :force => true do |t|
t.integer "branch_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "lineitems", :force => true do |t|
t.integer "cart_id"
t.integer "part_id"
t.integer "package_id"
t.integer "quantity", :default => 1
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "parts", :force => true do |t|
t.string "description"
t.string "partNumber"
t.decimal "price"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "packages", :force => true do |t|
t.string "description"
t.string "name"
t.string "img_src"
t.decimal "price"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
The above form works but...
Question 1: How to show the package.name instead of :package_id
Question 2: How to display total_price of each lineitem in the form. It is a method how would that work?
Question 3: Is there a best practice to displaying a form in an invoice looking manner where maybe the quantity is a text field but the remainder of the columns are just text or labels?
The end game scenario is this form will be a last chance to edit the quantities of the cart (or remove lineitems) before submitting an order. Obviously in the real world you want to display the quantities, package name, description and price but I can't seem to figure out how to display those values inside the form since they are in another model by relationship and not specific to lineitems.
Thanks for the help.
You are looking for the ActionView::Helpers::ActiveModelInstanceTag#object method. This gives you access to ActiveRecord everywhere inside the form.
1
<% if f.object.package_id? %>
<%= text_field_tag :package_name, f.object.package.name %>
<%= f.hidden_field :package_id %>
<% else %>
2 <%= f.object.total_price %>
3 Perhaps try the :readonly => true option on all input tags except the quantity?

(undefined method `name' for #<User:0x00000005f63ee8>) Devise; Ruby on Rails 3.2.1

I have this error in heroku logs:
Maybe this is because I have added name, surname and phone fields at registration? Locally my project is working fine, without problems.
User model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :surname, :phone
end
Devise registration form:
<div id="content">
<h1 class="title">Reģistrēt jaunu profilu.</h1>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="virslauks">
<span class="text2">
<%= f.label :name, "Vārds:" %><br />
<%= f.text_field :name %><br />
<%= f.label :surname, "Uzvārds:" %><br />
<%= f.text_field :surname %><br />
</span>
</div>
<div class="virslauks">
<span class="text2">
<%= f.label :phone, "Telefona Nr.:" %><br />
<%= f.phone_field :phone %>
</span>
</div>
<div class="virslauks">
<span class="text2">
<%= f.label :email, "E-pasts:" %><br />
<%= f.email_field :email %>
</span>
</div>
<div class="virslauks">
<span class="text2">
<%= f.label :password, "Parole:" %><br />
<%= f.password_field :password %><br />
<%= f.label :password_confirmation, "Vēlreiz parole:" %><br />
<%= f.password_field :password_confirmation %>
</span>
</div>
<%= f.submit "Reģistrēties" %>
<% end %>
devise_create_users:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## User details
t.string :name, :null => false, :default => ""
t.string :surname, :null => false, :default => ""
t.integer :phone, :null => false, :default => ""
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Encryptable
# t.string :password_salt
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
end
PROBLEM SOLVED:
I have solved the problem. I simply added
add_index :users, :name, :surname, :phone
in devise_create_users
Is name a column in your database? Note, it is not there by default with devise. If so, did you run rake db:migrate?

Resources