我尝试将rails-3.2-model更改为rails 4,但我不明白。
也许您可以帮助我进行更改。
3.2:
class User < ActiveRecord::Base
attr_accessible :email, :username, :password, :password_confirmation
attr_accessor :password
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email, :on => :create
validates_presence_of :username, :on => :create
validates_uniqueness_of :email
validates_uniqueness_of :username
def self.authenticate(email, password)
user = find_by_email(email)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
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
4.0.4:
class User < ActiveRecord::Base
validates :name, presence: true, uniqueness: {case_sensitive: true}, length: {minimum: 3, too_short: "must have at least %{count} characters"}
validates :email, presence: true, uniqueness: {case_sensitive: true}
validates :password_hash
end
我试图摆脱attr_accessible
和attr_accessor
,但我不知道如何。
attr_accessor :password
并且attr_accessible [...] :password_confirmation
没有存储在数据库中,那么如何在我的视图中使用它?
编辑:
查看:
<p>Sign Up</p>
<%= form_for @user, :as => :user, :url => auth_sign_up_path, :html => {:class => 'navbar-form', :role => 'login'} do |user_form_builder| %>
<p>
<%= user_form_builder.label 'name:' %><br/>
<%= user_form_builder.text_field :name %>
<%= show_field_error(@user, :name) %>
</p>
<p>
<%= user_form_builder.label 'email:' %><br/>
<%= user_form_builder.text_field :email %>
<%= show_field_error(@user, :email) %>
</p>
<p>
<%= user_form_builder.label 'password:' %><br/>
<%= user_form_builder.password_field :password %>
<%= show_field_error(@user, :password) %>
</p>
<p>
<%= user_form_builder.label 'password confirmation:' %><br/>
<%= user_form_builder.password_field :password_confirmation %>
<%= show_field_error(@user, :password_confirmation) %>
</p>
<p>
<%= user_form_builder.submit 'Sign Up' %>
<%= user_form_builder.submit 'Clear Form', :type => 'reset' %>
</p>
<% end %>
控制器:
def sign_up
@user = User.new
end
def register
@user = User.new(user_params)
if @user.valid?
@user.save
session[:user_id] = @user.id
flash[:notice] = 'Welcome.'
redirect_to :root
else
render :action => "sign_up"
end
end
private
def user_params
params.require(:user).permit(:email, :name, :password, :password_confirmation)
end
模型:
require 'bcrypt'
class User < ActiveRecord::Base
attr_accessor :name, :email, :password, :password_confirmation
before_save :encrypt_password
after_save :clear_password
validates :name, presence: true, uniqueness: {case_sensitive: true}, length: {minimum: 3, too_short: "must have at least %{count} characters"}
validates :email, presence: true, uniqueness: {case_sensitive: true}
validates :password, presence: true, length: {minimum: 8, too_short: "must have at least %{count} characters"}, :confirmation => true #password_confirmation attr
def initialize(attributes = {})
super # must allow the active record to initialize!
attributes.each do |name, value|
send("#{name}=", value)
end
end
def self.authenticate_by_email(email, password)
user = find_by_email(email)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
def self.authenticate_by_name(name, password)
user = find_by_username(name)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
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
def clear_password
self.password = nil
end
end
移民:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.string :password_hash
t.string :password_salt
t.string :cal_owner, :array => true, :default => '{}'
t.string :cal_joined, :array => true, :default => '{}'
t.timestamps
end
end
end
路线:
Calendar::Application.routes.draw do
# You can have the root of your site routed with "root"
root 'welcome#index'
get "auth/sign_up" => "auth#sign_up"
get "auth/sign_in" => "auth#sign_in"
get "auth/sign_out" => "auth#sign_out"
get "auth/settings"
get "auth/pwd_reset"
get "welcome/index"
post "auth/sign_in" => "auth#login"
post "auth/sign_up" => "auth#register"
end
我使用了一个教程,但是我不知道为什么作者要添加以下内容:
def initialize(attributes = {})
super # must allow the active record to initialize!
attributes.each do |name, value|
send("#{name}=", value)
end
end
作者写道:
对于每个键值对(哈希),我们通过调用“发送”函数将值分配给属性(Ruby中的所有方法调用实际上都是消息。)
重要的:
实际上,我们不需要为User类执行此操作,因为Rails提供的构造函数将允许我们从哈希中进行“批量分配”,只要我们分配的字段已被指定为“ attr_accessible”即可,他们有。但是,在某些情况下,您可能希望初始化几个字段(例如多对多表中的ID),这些字段原本不是视图可访问的,而是使用“ attr_accessor”指定的。上面的函数是为内部构造函数提供安全的批量分配功能的简单方法。
据我了解,您的用户表除了在ID等处创建的ID外,实际上还有4列:
在您的视图中,您具有以下字段:
您的控制器看起来正确。该user_params
方法是将视图中的4个字段列入白名单,并将其传递给User模型以创建新用户。
在模型中,您需要进行2次更改。
首先,您应该从以下行中删除name
和:email
attr_accessor
attr_accessor :password, :password_confirmation
您只需要password
和password_confirmation
。这样做的原因是因为name和email是数据库中的列,Rails会自动为您提供这些属性的getter和setter方法。attr_accessor
然后省去了必须为和显式编写getter和setter方法的麻烦password
,password_confirmation
并允许它们在使用视图中的值创建新用户时自动填充它们。
其次,您应该删除该initialize
方法。无需构造函数即可User
继承ActiveRecord::Base
并能够愉快地构建新的用户记录。
本教程的作者包括进行批量分配的构造函数。但是,在Rails 4中,已将其更改为使用强参数,因此控制器现在有责任声明可以将哪些参数传递给模型。您可以user_params
在控制器中的方法中正确执行此操作。
我希望这有帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句