我正在 rails 制作体育排行榜,并尝试使用从其他列计算的值来批量指定列。以下是列的名称::pts
,:games_played
和:pts_per_game
。前两个已经分配了值,我想通过除以pts by:games_played 将值插入到最后一个值中。所以我去了rails console并尝试了
PlayerLeaderboard.update_all(pts_per_game: pts/games_played)
但是我使用NoMethodError获取此输出
NoMethodError: undefined method `pts' for main:Object
from (irb):24
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in `start'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in `start'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in `console'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/commands.rb:17:in `<top (required)>'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `require'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `block in require'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `require'
from /Users/AYL/Dropbox/workspace/rails/krossover/bin/rails:8:in `<top (required)>'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/commands/rails.rb:6:in `call'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/command_wrapper.rb:38:in `call'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/application.rb:183:in `block in serve'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/application.rb:156:in `fork'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/application.rb:156:in `serve'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/application.rb:131:in `block in run'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/application.rb:125:in `loop'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/application.rb:125:in `run'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.3.6/lib/spring/application/boot.rb:18:in `<top (required)>'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/AYL/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from -e:1:in `<main>'irb(main):025:0>
奇怪的是我以前尝试过这种方法并且有效。我刚刚将我的开发数据库从sqlite3切换到postgres和重新种子数据。我似乎不太可能切换db是导致此错误的原因;我一定错过了什么
我也试过了update_column
。
提前致谢!
答案 0 :(得分:0)
您可以使用ActiveRecord执行此操作:
PlayerLeaderboard.update_all("pts_per_game = pts/games_played")
答案 1 :(得分:0)
该代码将pts
和games_played
视为self
上的局部变量或方法。没有这样的方法,因此错误。
你想要列,所以你需要将一些SQL发送到update_all
而不是Ruby哈希:
PlayerLeaderboard.update_all('pts_per_game = pts / games_played')
据推测,pts
和games_played
是整数列,因此您将在这里遇到截断问题。如果这就是你想要的(即5 / 3
为1
)那么就没有什么可担心的了。如果你的pts_per_game
是浮点数,那么你需要在混合中投掷一个角色:
PlayerLeaderboard.update_all('pts_per_game = cast(pts as float) / games_played')
PlayerLeaderboard.update_all('pts_per_game = pts::float / games_played')
cast
是标准SQL,::
语法是特定于PostgreSQL的。
如果你的pts_per_game
是一个整数而你想要它是四舍五入的,那么你必须这样说:
PlayerLeaderboard.update_all('pts_per_game = round(cast(pts as float) / games_played)')
如果可能出现负值,则您需要使用ceil
或floor
代替round
来选择负值应该舍入的方向。
如果你在games_played
中有零,那么你需要做两次更新并决定当没有任何游戏时pts_per_game
应该是什么,零和NULL是合理的选择我想:
PlayerLeaderboard.where(:games_played => 0).update_all(...)
PlayerLeaderboard.where.not(:games_played => 0).update_all(:pts_per_game => 0)
如果你没有任何游戏时pts_per_game
为NULL,那么你只需要第一个update_all
,因为默认情况下新列是NULL。