gpt4 book ai didi

ruby-on-rails - 为什么update_attributes破坏了我的Rails应用程序?

转载 作者:行者123 更新时间:2023-12-03 15:58:41 24 4
gpt4 key购买 nike

原始问题

我在Ruby 1.9.2上运行Rails 3.0.1。这是相关的模型,控制器和视图。



user.rb:

class User < ActiveRecord::Base
belongs_to :directory

attr_accessor :new_password, :new_password_confirmation

validates_confirmation_of :new_password, :if => :password_changed?

before_save :hash_password, :if => :password_changed?

def self.authenticate(login, password)

# Check to see if the user exists
if user = find_by_login(login)

# If this is an directory user, authenticate them against their directory
if user.directory
return directory_auth user, password

# Otherwise, authenticate them against the local database
elsif user.hash == Digest::SHA2.hexdigest(user.salt + password)
return user
end
end
return nil
end

def password_changed?
!@new_password.blank?
end

private

def hash_password
self.salt = ActiveSupport::SecureRandom.base64 8
self.hash = Digest::SHA2.hexdigest(self.salt + @new_password)
end

def self.directory_auth(user, password)

directory = user.directory
directory.bind['%s'] = user.login

ldap = Net::LDAP.new
if directory.use_simple_tls?
ldap.encryption :simple_tls
end
ldap.host = directory.host
ldap.port = directory.port
ldap.auth directory.bind, password

return user if ldap.bind
return nil
end
end


users_controller.rb:

class UsersController < ApplicationController

def index
@users = User.all
end

def show
@user = User.find params[:id]
end

def new
@user = User.new
end

def create
@user = User.new params[:user]

if @user.save
flash[:notice] = "#{@user.login} was created"
redirect_to @user
else
flash[:notice] = 'The user could not be created'
render :action => 'new'
end
end

def edit
@user = User.find params[:id]
end

def update
@user = User.find params[:id]

@user.attributes = params[:user] # this works
# @user.update_attributes params[:user] # this does NOT work

if @user.save # I realize this is redundant if update_attributes is working
flash[:notice] = "#{@user.login} was updated"
redirect_to @user
else
flash[:notice] = 'The user could not be updated'
render :action => 'edit'
end
end

def destroy
@user = User.find params[:id]
@user.destroy

flash[:notice] = "#{@user.login} was deleted"
redirect_to users_url
end
end


users.html.erb:

<%= form_for @user do |f| %>
<%= f.label :login %>:
<%= f.text_field :login %>
<br>
<%= f.label :new_password %>:
<%= f.password_field :new_password %>
<br>
<%= f.label :new_password_confirmation %>:
<%= f.password_field :new_password_confirmation %>
<br>
<% if directories = Directory.all.empty? %>
No directories defined. You can <%= link_to 'add a directory', new_directory_path %>.
<% else %>
<%= f.label :directory_id %>:
<%= f.collection_select :directory_id, Directory.all, :id, :name, { :include_blank => 'None' } %>
<% end %>
<br>
<%= f.label :admin, 'Administrator?' %>:
<%= f.check_box :admin %>
<br>
<%= f.submit %>
<% end %>


schema.rb:

ActiveRecord::Schema.define(:version => 20101107005603) do

create_table "directories", :force => true do |t|
t.string "host"
t.string "bind"
t.boolean "use_simple_tls"
t.integer "port"
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "users", :force => true do |t|
t.string "login"
t.string "hash"
t.string "salt"
t.boolean "admin"
t.integer "directory_id"
t.datetime "created_at"
t.datetime "updated_at"
end

end


我有另一个非常相似的目录模型/控制器/视图,但是没有虚拟访问器或其他模型ID,并且 update_attributes可以很好地工作。我使用 rails g scaffold users name:string password:string做了一个快速测试应用程序,所有CRUD动作均正常运行。

这真让我发疯!我找到了一种解决方法,但是我真的想了解为什么 update_attributes在这里不起作用。当我运行更新操作时,得到以下信息:

UsersController#update中的TypeError

无法将nil转换为Integer

Rails.root:/ home / force / proj

app / controllers / users_controller.rb:34:在“更新”中

全栈跟踪

activerecord(3.0.1)lib / active_record / connection_adapters / abstract / database_statements.rb:318:在'uniq'中
activerecord(3.0.1)lib / active_record / connection_adapters / abstract / database_statements.rb:318:在'commit_transaction_records'中
activerecord(3.0.1)lib / active_record / connection_adapters / abstract / database_statements.rb:165:在'事务'中
activerecord(3.0.1)lib / active_record / transactions.rb:204:在'transaction'中
activerecord(3.0.1)lib / active_record / transactions.rb:287:in withwith_transaction_returning_status'
activerecord(3.0.1)lib / active_record / persistence.rb:126:在“ update_attributes”中
app / controllers / users_controller.rb:34:在“更新”中
actionpack(3.0.1)lib / action_controller / metal / implicit_render.rb:4:in'send_action'
actionpack(3.0.1)lib / abstract_controller / base.rb:150:在`process_action'中
actionpack(3.0.1)lib / action_controller / metal / rendering.rb:11:在'process_action'中
actionpack(3.0.1)lib / abstract_controller / callbacks.rb:18:在'process_action中的块'中
activesupport(3.0.1)lib / active_support / callbacks.rb:435:在_run__805567340__process_action__482539529__callbacks中
activesupport(3.0.1)lib / active_support / callbacks.rb:409:在“ _run_process_action_callbacks”中
activesupport(3.0.1)lib / active_support / callbacks.rb:93:在`run_callbacks'中
actionpack(3.0.1)lib / abstract_controller / callbacks.rb:17:在'process_action'中
actionpack(3.0.1)lib / action_controller / metal / instrumentation.rb:30:in'process_action中的块'
activesupport(3.0.1)lib / active_support / notifications.rb:52:在'仪器中的块'中
activesupport(3.0.1)lib / active_support / notifications / instrumenter.rb:21:in`instrument'中
activesupport(3.0.1)lib / active_support / notifications.rb:52:在'instrument'中
actionpack(3.0.1)lib / action_controller / metal / instrumentation.rb:29:在`process_action'中
actionpack(3.0.1)lib / action_controller / metal / rescue.rb:17:在'process_action'中
actionpack(3.0.1)lib / abstract_controller / base.rb:119:在'process'中
actionpack(3.0.1)lib / abstract_controller / rendering.rb:40:在'process'中
actionpack(3.0.1)lib / action_controller / metal.rb:133:在`dispatch'中
actionpack(3.0.1)lib / action_controller / metal / rack_delegation.rb:14:in`dispatch'
actionpack(3.0.1)lib / action_controller / metal.rb:173:in'动作中的块'
actionpack(3.0.1)lib / action_dispatch / routing / route_set.rb:62:在'call'中
actionpack(3.0.1)lib / action_dispatch / routing / route_set.rb:62:在`dispatch'中
actionpack(3.0.1)lib / action_dispatch / routing / route_set.rb:27:在'call'中
机架安装(0.6.13)lib / rack / mount / route_set.rb:148:in`block in call'
机架安装(0.6.13)lib / rack / mount / code_generation.rb:93:in``识别中的块''
机架安装(0.6.13)lib / rack / mount / code_generation.rb:103:在`optimized_each'中
机架安装(0.6.13)lib / rack / mount / code_generation.rb:92:在`recognize'中
机架安装(0.6.13)lib / rack / mount / route_set.rb:139:在`call'中
actionpack(3.0.1)lib / action_dispatch / routing / route_set.rb:492:in`call'
actionpack(3.0.1)lib / action_dispatch / middleware / best_standards_support.rb:17:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / head.rb:14:在`call'中
机架(1.2.1)lib / rack / methodoverride.rb:24:in`call'
actionpack(3.0.1)lib / action_dispatch / middleware / params_parser.rb:21:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / flash.rb:182:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / session / abstract_store.rb:149:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / cookies.rb:287:在`call'中
activerecord(3.0.1)lib / active_record / query_cache.rb:32:在“通话中阻止”中
activerecord(3.0.1)lib / active_record / connection_adapters / abstract / query_cache.rb:28:在“缓存”中
activerecord(3.0.1)lib / active_record / query_cache.rb:12:在“缓存”中
activerecord(3.0.1)lib / active_record / query_cache.rb:31:在'call'中
activerecord(3.0.1)lib / active_record / connection_adapters / abstract / connection_pool.rb:355:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / callbacks.rb:46:in在“阻止通话中”
activesupport(3.0.1)lib / active_support / callbacks.rb:415:在_run_call_callbacks中
actionpack(3.0.1)lib / action_dispatch / middleware / callbacks.rb:44:在`call'中
机架(1.2.1)lib / rack / sendfile.rb:107:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / remote_ip.rb:48:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / show_exceptions.rb:46:在`call'中
railties(3.0.1)lib / rails / rack / logger.rb:13:在`call'中
机架(1.2.1)lib / rack / runtime.rb:17:in`call'
activesupport(3.0.1)lib / active_support / cache / strategy / local_cache.rb:72:在'call'中
机架(1.2.1)lib / rack / lock.rb:11:in在通话中
:10:in在'synchronize'
机架(1.2.1)lib / rack / lock.rb:11:在`call'中
actionpack(3.0.1)lib / action_dispatch / middleware / static.rb:30:在`call'中
railties(3.0.1)lib / rails / application.rb:168:在`call'中
railties(3.0.1)lib / rails / application.rb:77:in`method_missing'
栏杆(3.0.1)lib / rails / rack / log_tailer.rb:14:在`call'中
机架(1.2.1)lib / rack / content_length.rb:13:在`call'中
机架(1.2.1)lib / rack / handler / webrick.rb:52:in`service'
/home/force/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/httpserver.rb:111:在`service'中
/home/force/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/httpserver.rb:70:在`run'中
/home/force/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/server.rb:183:在'start_thread中的块'中


请求参数

{“ utf8” =>“✓”,
“ _method” =>“放入”,
“ authenticity_token” =>“ OvMUeM9hqfPASC0NS + Th07GELu6B + dQCCTtm3gWdJE4 =”,
“用户” => {“登录” =>“本地”,
“ new_password” =>“ [已过滤]”,
“ new_password_confirmation” =>“ [已过滤]”,
“ directory_id” =>“”,
“ admin” =>“ 0”},
“ commit” =>“更新用户”,
“ id” =>“ 13”}


完整的源代码

如果您想尝试一下,可以在 http://github.com/sidewaysmilk/deezy下载完整的源代码,并编辑 app/controllers/users_controller.rb以在 @user.update_attributes params[:user]操作中使用 update

最佳答案

好。我真的很傻。我很惊讶没有人注意到这一点。

在我的模型中,我命名了我的属性之一。 hash,因此要访问它,我会说@user.hash

ActiveRecord :: Base#hash是already defined

所以我搞砸了。当ActiveRecord尝试执行事务时,它试图设置一个值,例如

@user.hash = password_hash


ActiveRecord::Base#hash=需要一个整数,如果更改密码,则 password_hash输出一个String,否则为nil。

所以永远不要命名列哈希!选择列名时请查阅文档,以避免发生冲突。

关于ruby-on-rails - 为什么update_attributes破坏了我的Rails应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4129292/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com