Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 为什么当我的其他属性有值时,我的[:Rating]属性为nil?_Ruby On Rails_Ruby_Activerecord_Attributes_Null - Fatal编程技术网

Ruby on rails 为什么当我的其他属性有值时,我的[:Rating]属性为nil?

Ruby on rails 为什么当我的其他属性有值时,我的[:Rating]属性为nil?,ruby-on-rails,ruby,activerecord,attributes,null,Ruby On Rails,Ruby,Activerecord,Attributes,Null,我正试图建立一个评级系统。我最近升级了我的迁移文件 class AddRatingsToPictures < ActiveRecord::Migration def change add_column :pictures, :ratings_count, :integer add_column :pictures, :rating_total, :integer add_column :pictures, :rating, :integer end end

我正试图建立一个评级系统。我最近升级了我的迁移文件

class AddRatingsToPictures < ActiveRecord::Migration
  def change
    add_column :pictures, :ratings_count, :integer
    add_column :pictures, :rating_total, :integer
    add_column :pictures, :rating, :integer
  end
end
下面是我在Rails控制台中尝试的一些东西

p = Picture.find(1)
p.rating == nil
false
p[:rating] == nil
true
我认为问题在于这个片段

def rating
  self[:rating] || 0
  return 0 if self.ratings_count == 0
  (self.rating_total.to_f / self.ratings_count).round(2)
end
如果我对一个对象调用.rating,它将返回正确的等级。如果我对一个对象调用[:rating],它将返回nil

我问这个问题的原因是因为我需要这个用于活动记录查询,在这里我必须调用实际属性。具体来说,这行代码

<% Picture.where("rating >= 4.5").order(rating: :desc, title: :asc).each do |picture|  %>
因此,我的方法似乎可以为我的模型创建属性。原因可能是我的add_评级方法

def add_rating(rating)
  return if rating.nil? || rating == 0

  self.ratings_count += 1
  self.rating_total += rating.to_i
  self.stars = (self.rating_total.to_f / self.ratings_count)
  self.save
end
上面,我调用了save方法,它可能在模型中记录了属性


我想我已经很接近了,但看起来我需要帮助。任何建议都将不胜感激。提前感谢。

这可能无法解决添加评级的问题,但您可以在迁移中设置默认值,使它们永远不会为零,并且您可以简化每个方法的逻辑,这样可能更容易跟踪问题

class AddRatingsToPictures < ActiveRecord::Migration
  def change
    add_column :pictures, :ratings_count, :integer, default: 0
    add_column :pictures, :rating_total, :integer, default: 0
    add_column :pictures, :rating, :integer, default: 0
  end
end
class AddRatingsToPictures
picture[:rating]
返回列在数据库中的实际属性值,因此,如果数据库中的值未设置,它将返回
nil
,即使您在迁移中将类型设置为整数

在您的代码中,有许多条件,如
self[:rating]| | 0
if rating.nil?|评级==0
。这变得越来越复杂,因为您期望
nil
0
。克服这种复杂性的最简单方法是告诉数据库不允许空值,并设置一些默认值(在您的示例中为0)。您应该进行如下迁移:

class AddRatingsToPictures < ActiveRecord::Migration
  def change
    add_column :pictures, :ratings_count, :integer, null: false, default: 0
    add_column :pictures, :rating_total, :integer, null: false, default: 0
    add_column :pictures, :rating, :integer, null: false, default: 0
  end
end
现在,看看代码,您正在将一些属性
星号
设置为平均评级。实际的
评级
属性根本没有设置。没有足够的信息让我确定,但我假设
明星
应该是
评级
?那么你会得到:

def add_rating(rating)
  return if rating.to_i == 0

  self.ratings_count += 1
  self.rating_total += rating.to_i
  self.rating = (rating_total.to_f / ratings_count)
  self.save
end

好吧,我解决了问题。这是因为我将评级存储为整数,而不是小数

add_column :pictures, :rating, :integer, default: 0, null: false
应该是

add_column :pictures, :rating, :decimal, default: 0, null: false
我的方法要求我将ratings_total除以ratings_count的整数。我使用类型转换将数字转换为十进制,但值本身存储为整数


更改迁移解决了这个问题。

我认为这不是答案。我的ratings\u count和ratings\u total属性不是零,我没有包括默认值:0。这可能值得一看。这是有潜力的,不幸的是,这条线是一个问题。自我评级\总+=评级。这将导致TypeError:无法将字符串强制转换为fixnum。我知道我们将类型设置为整数,但可能需要先将rating_total转换为浮点。我会调查的。我们还删除了ratings_total和ratings_count方法。我猜参数应该是字符串。我更新了答案,将其转换为整数。你已经准备好了这个角色,我想我有点太想移除它了;)很好,这解决了我的问题。但是[:rating]仍然设置为0,而不是计算的等级。
def add_rating(rating)
  return if rating.to_i == 0

  self.ratings_count += 1
  self.rating_total += rating.to_i
  self.rating = (rating_total.to_f / ratings_count)
  self.save
end
add_column :pictures, :rating, :integer, default: 0, null: false
add_column :pictures, :rating, :decimal, default: 0, null: false