动态更新ActiveRecord对象属性
动态更新ActiveRecord对象属性
我想使用从另一个来源访问的属性名称更新AR对象(在实际数据中有很多)。
class DailyScore < ActiveRecord::Base attr_accessor :mail, :date, :sun, :express, :average end array = ['mail','date','sun'] thing = DailyScore.new
我该如何将数组中的每个项转换为符号,并相应地更新记录?
理想情况下,我想要这样的东西:
array.each do |field| thing.field = 1.0 #Float end
更新(带有更完整的代码示例):
def sort_and_deliver_scores(dates) # dates example: ["2016-01-01","2016-01-12","2016-01-05"] dates.each do |dateString| params = {} params[:date] = dateString so_far = 0.0 ["mail","express","sun"].each do |paper| # get all records that correspond to this newspaper @dailyscores = MyModel .pluck(:paper,:score, :date) .select{|b| b[0]==paper} # add up the scores in all records for each paper that day today = @dailyscores.map{|c| c[1]}.inject(:+) todaysScoresByPaper = (today/@dailyscores.size).round(1) so_far += todaysScoresByPaper params[paper.to_sym] = todaysScoresByPaper end params[:average] = (so_far / 3).round(1) save_record_as_daily_score_object(params) end end def save_record_as_daily_score_object(params) ds = DailyScore.where(date: params[:date]).first_or_create! ds.update!(params) end
当我使用Pry进行检查时,参数很好,Float值存储在哈希中,但由于某种原因,当我保存记录时,只有:average字段被保存,而其他所有字段都是nil。
更新2:
tasks.rake
task :seed_scores => :environment do # "select_a_few_dates" sends a few dates as strings sort_and_deliver_scores(Score.all.select_a_few_dates) end
score.rb
def save_record_as_daily_score_object(params) ds = DailyScore.where(date: params[:date]).first_or_create! ds.update!(params) binding.pry end PRY output: [1] pry(main)> ds => # [2] pry(main)> params => {:date=>"2015-09-02", :mail=>-0.6, :express=>-0.1, :sun=>-3.2, :average=>-3.4}
看来按dateString创建DailyScore对象不起作用,由于某种原因,只有:average属性被保存。
admin 更改状态以发布 2023年5月24日
这样就可以搞定啦 🙂
array = ['title', 'date', 'height'] thing = Thing.new array.each do |field| thing.send("#{field}=", 'your value') end # save object or do whatever
send 调用由符号或字符串定义的方法(就像我们的例子)。
你可以使用ActiveRecord哈希接口,使用你的数组变量,看起来像这样:
array.each do |field| thing[field.to_sym] = "I'll tell you later" end thing.save
或者,你可以使用params哈希方法。Rails使用params哈希执行类似的操作。你可以以这种方式模拟这种功能:
array = ['title','date','height'] values = ['King Lear', '2016-05-13', 13.5] attributes_hash = {} array.map {|elem| elem.to_sym }.each_with_index do |field, i| attributes_hash[field] = values[i] end thing.update(attributes_hash)
这种方法的好处是,你可以一次更新整个哈希值。如果你想绕过验证和其他检查,你可以使用update_attributes。
更多信息请参见: