我在PostgreSQL中创建了我的数据库并进行了迁移。当我尝试将新数据保存到其中时,我收到了这个错误:
I wrote this refactoring tool.
这是我的代码:
我的布局:
<form method="post" action="/signup">
<div class="form-group">
<label>Username</label>
<input type="text" class="form-control" placeholder="Name" name="user[username]">
</div>
<div class="form-group">
<label>Email address</label>
<input type="email" class="form-control" placeholder="Email" name="user[email]">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" placeholder="Password" name="user[password]">
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" class="form-control" placeholder="Confirm Password" name="user[confirm_password]">
</div>
<button type="submit" class="btn btn-info">Sign up</button>
</form>
我的控制器:
post '/signup' do
user = User.new(params[:user])
user.create_user
end
我的模特:
require 'bcrypt'
class User < ActiveRecord::Base
include BCrypt
# This is Sinatra! Remember to create a migration!
validates :email, :format => { :with => /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i ,
:message => "Email wrong format" }
validates :email, uniqueness: true
def initialize(signup)
#@signup = signup
@username = signup["username"]
@email = signup["email"]
@password = signup["password"]
end
def test
p @signup
end
def create_user
p_p = Password.create(@password)
p_h ||= Password.new(p_p)
user_hash = {:username => @username,:email => @email, :encrypted_password => p_h}
User.create(user_hash)
end
end
完整回溯
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5.1/lib/active_record/transactions.rb in clear_transaction_record_state
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5.1/lib/active_record/transactions.rb in ensure in rollback_active_record_state!
clear_transaction_record_state
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5.1/lib/active_record/transactions.rb in rollback_active_record_state!
clear_transaction_record_state
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5.1/lib/active_record/transactions.rb in save
rollback_active_record_state! do
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5.1/lib/active_record/persistence.rb in create
object.save
/Sites/nextAcademy/quora_clone/code/app/models/user.rb in create_user
return User.create(user_hash)
/Sites/nextAcademy/quora_clone/code/app/controllers/static.rb in block in <top (required)>
"#{user.create_user}"
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
proc { |a,p| unbound_method.bind(a).call }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in compile!
proc { |a,p| unbound_method.bind(a).call }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in []
route_eval { block[*args] }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block (3 levels) in route!
route_eval { block[*args] }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in route_eval
throw :halt, yield
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block (2 levels) in route!
route_eval { block[*args] }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in process_route
block ? block[self, values] : yield(self, values)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in catch
catch(:pass) do
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in process_route
catch(:pass) do
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in route!
returned_pass_block = process_route(pattern, keys, conditions) do |*args|
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in each
routes.each do |pattern, keys, conditions, block|
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in route!
routes.each do |pattern, keys, conditions, block|
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in dispatch!
route!
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in invoke
res = catch(:halt) { yield }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in catch
res = catch(:halt) { yield }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in invoke
res = catch(:halt) { yield }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in dispatch!
invoke do
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in call!
invoke { dispatch! }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in invoke
res = catch(:halt) { yield }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in catch
res = catch(:halt) { yield }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in invoke
res = catch(:halt) { yield }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call!
invoke { dispatch! }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
dup.call!(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/session/abstract/id.rb in context
status, headers, body = app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/session/abstract/id.rb in call
context(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb in call
status, headers, body = @app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb in call
app.call env
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb in call
status, headers, body = app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
result or app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
result or app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb in call
status, headers, body = @app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/logger.rb in call
@app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
env['sinatra.commonlogger'] ? @app.call(env) : super
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/head.rb in call
status, headers, body = @app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/methodoverride.rb in call
@app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/show_exceptions.rb in call
@app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
result, callback = app.call(env), env['async.callback']
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
@stack.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in call
synchronize { prototype.call(env) }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in synchronize
yield
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
synchronize { prototype.call(env) }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/lint.rb in _call
status, headers, @body = @app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/lint.rb in call
dup._call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/showexceptions.rb in call
@app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/commonlogger.rb in call
status, header, body = @app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
call_without_check(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/shotgun-0.9.1/lib/shotgun/loader.rb in proceed_as_child
status, headers, body = assemble_app.call(@env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/shotgun-0.9.1/lib/shotgun/loader.rb in call!
proceed_as_child
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/shotgun-0.9.1/lib/shotgun/loader.rb in call
dup.call!(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/shotgun-0.9.1/lib/shotgun/favicon.rb in call
app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/shotgun-0.9.1/lib/shotgun/static.rb in call
@app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/urlmap.rb in block in call
return app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/urlmap.rb in each
@mapping.each do |host, location, match, app|
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/urlmap.rb in call
@mapping.each do |host, location, match, app|
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/builder.rb in call
to_app.call(env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/thin-1.6.4/lib/thin/connection.rb in block in pre_process
response = @app.call(@request.env)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/thin-1.6.4/lib/thin/connection.rb in catch
catch(:async) do
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/thin-1.6.4/lib/thin/connection.rb in pre_process
catch(:async) do
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/thin-1.6.4/lib/thin/connection.rb in process
post_process(pre_process)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/thin-1.6.4/lib/thin/connection.rb in receive_data
process if @request.parse(data)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb in run_machine
run_machine
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb in run
run_machine
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/thin-1.6.4/lib/thin/backends/base.rb in start
EventMachine.run(&starter)
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/thin-1.6.4/lib/thin/server.rb in start
@backend.start { setup_signals if @setup_signals }
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/thin.rb in run
server.start
/Users/manjarb/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/shotgun-0.9.1/bin/shotgun in <top (required)>
server.run app, options do |inst|
/Users/manjarb/.rbenv/versions/2.2.3/bin/shotgun in load
load Gem.bin_path('shotgun', 'shotgun', version)
/Users/manjarb/.rbenv/versions/2.2.3/bin/shotgun in <main>
load Gem.bin_path('shotgun', 'shotgun', version)
有谁知道为什么会发生这种情况?
答案 0 :(得分:1)
是否有理由(除了缺乏熟悉程度)不使用ActiveRecord回调?我认为如果你让ActiveRecord做的话,你的解决方案可能会相当简单......
class User < ActiveRecord::Base
attr_accessor :password
validates :username, presence: true, uniqueness: true
validates :email, format: { with: /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i, message: 'Invalid email format' },
uniqueness: true,
presence: true
validates :encrypted_password, presence: true
before :validation, :encrypt_password, if: :password_present?
private
def password_present?
!password.nil? && !password.length.zero?
end
def encrypt_password
self.encrypted_password = Password.new(password)
end
end
在上面的示例中,“before:validation”行告诉活动记录在执行验证之前调用encrypt_password方法,但前提是密码已经提供。在这种情况下,它将根据调用者提供的“密码”值为encrypted_password属性分配一个新密码。
请注意,代码假定密码未持久保存到数据库(仅保存encrypted_password)。如果没有db-backed密码列,则需要显式公开密码属性才能使其生效。您基本上通过代码中的@password实例变量解决了这个问题。
使用类似建议的类,您的控制器将成为
post '/signup' do
user = User.create(params[:user])
end
答案 1 :(得分:1)
你的问题是你正在扩展ActiveRecord::Base
类,并覆盖它的构造函数。因此,ActiveRecord::Base
所依赖的几个属性未初始化。尝试将super()
添加到构造函数中,如下所示:
def initialize(signup)
super()
#@signup = signup
@username = signup["username"]
@email = signup["email"]
@password = signup["password"]
end
或者,完全删除构造函数并将signup
哈希值传入create_user
方法。