gpt4 book ai didi

mysql - 在 Ruby 和 Rails 中使用计算

转载 作者:行者123 更新时间:2023-11-29 08:43:46 25 4
gpt4 key购买 nike

首先让我为一个看似简单的问题道歉,但作为 Rails、Ruby 和编程新手,我觉得我已经用尽了“Rails 新手”教程。

这就是我所面临的问题。

我有一个用户模型和机构模型,它们具有“has_many :through => :company_reps”关系。

用户具有基本字段(姓名、电子邮件、密码)(我正在使用 devise )

机构有很多字段,但相关字段是(客户 = bool 值、领导 = bool 值、demo_date = 日期/时间)更复杂的是,每个机构可以拥有一到两个用户,但大多数只有一个。

我们正在为用户举办一场竞赛,我需要根据 demo_date 字段和 client 字段向每个用户奖励积分。

因此,首先我需要做的是为每个用户提供与作为客户的机构相关的 10 分,除非该机构有 2 个用户,在这种情况下,我需要为这两个用户各提供 5 分。

其次,我需要为与演示日期在 2012 年 2 月之后的机构相关的所有用户提供 1 分。

我正在使用 Ruby 1.9.2、Rails 3.2.8 和 MySQL

  • 那么,我该如何实现这一目标呢?
  • 我是否应该创建一个新的表格和模型来存储这些点,如果是的话,如何保存计算结果?
  • 我应该将所有计算放入用户模型还是机构模型中?

一如既往地感谢您的帮助。

MySQL机构信息

CREATE TABLE `institutions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`state_id` int(11) DEFAULT NULL,
`company` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`clientdate` datetime DEFAULT NULL,
`street` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`city` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`zip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`source` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`source2` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`demodate1` datetime DEFAULT NULL,
`demodate2` datetime DEFAULT NULL,
`demodate3` datetime DEFAULT NULL,
`client` tinyint(1) DEFAULT NULL,
`prospect` tinyint(1) DEFAULT NULL,
`alead` tinyint(1) DEFAULT NULL,
`notcontacted` tinyint(1) DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7805 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

制度模式

class Institution < ActiveRecord::Base
attr_accessible :company, :phone, :assets, :clientdate, :street, :city, :state_id, :zip, :source, :source2, :demodate1, :demodate2, :demodate3, :client, :prospect, :alead, :notcontacted
belongs_to :state
has_many :users, :through => :company_reps
has_many :company_reps

end

用户模型

class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable

# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name
# attr_accessible :title, :body

has_many :states, :through => :rep_areas
has_many :institutions, :through => :company_reps
has_many :rep_areas
has_many :company_reps

def name
first_name + " " + last_name
end


end

公司代表模型

class CompanyRep < ActiveRecord::Base
belongs_to :user
belongs_to :institution
end

最佳答案

更新(因为我的第一次尝试错误地假设 User has_one :institution

最简单的选择是对 Institution 进行基本计算模型来建立机构“值得”多少积分,然后将该值相加来计算用户的积分。

# Institution
def points
points_for_client + points_for_demo_date
end

private

def points_for_client
if client?
10 / users.count
else
0
end
end

def points_for_demo_date
if demo_date.present? && demo_date >= Date.new(2012, 3, 1)
1
else
0
end
end

请注意,您可以压缩这些 if使用三元运算符将语句转换为单行语句 ? :如果你更喜欢。另请注意,我假设“2 月之后”的意思是“从 3 月 1 日起”。

支票为零 demo_date也是一个品味问题。从中选择

# Verbose, but IMO intention-revealing
demo_date.present? && demo_date >= Date.new(...)

# Perhaps more idiomatic, since nil is falsy
demo_date && demo_date >= Date.new(...)

# Take advantage of the fact that >= is just another method
# Concise, but I think it's a bit yuk!
demo_date.try :>=, Date.new(...)

既然每个机构都有一定的分数,那么将它们总结起来就相当简单了:

# User
def points
institutions.inject(0) {|sum, institution| sum + institution.points }
end

查看the docs for inject 如果您不熟悉它,这是一个漂亮的小方法。

就性能而言,这并不是最理想的。一个基本的改进是记住结果:

# Institution
def points
@points ||= points_for_client + points_for_demo_date
end

# User
def points
@points ||= institutions.inject ...
end

以便进一步调用points在同一请求中不要重新计算该值。只要 client 就可以了和demo_date User 时请勿更改对象仍然存在:

some_user.points   #=> 0
some_user.institution.client = true
some_user.points #=> 0 ... oops

User对象将在下一个请求时重新创建,因此这可能不是问题(这取决于这些字段如何变化)。

您还可以添加 points字段到 User从而将该值保存在数据库中,使用原始版本作为 update_points方法代替

def update_points
self.points = institutions.inject ...
end

但是,确定何时重新计算该值将成为一个问题。

我的建议是尽可能保持简单并避免过早优化。这是一个相对简单的计算,因此只要您没有大量的用户和机构或大量的请求,它就不会成为一个大的性能问题。

关于mysql - 在 Ruby 和 Rails 中使用计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13053111/

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