在我的Rails应用程序中,创建业务时我有一个包含以下字段的表单:
<%= check_box_tag(:default_company) %>
<%= label_tag(:default_company, "Set Company as Default") %>
基本上,当我创建一个企业时,如果他们选中此框,我需要它来运行类似下面的代码:
def set_default_company(company, user)
exists = DefaultCompany.find(user.id)
if exists
exists.update_attributes(company: company)
else
DefaultCompany.create(company: company, user: user)
end
end
在学习的过程中,我通常会在我的控制器中执行这些操作,但我正在尝试遵循最佳实践并使用胖模型,瘦的控制器,所以我想要使用这样的逻辑:
def create
@company = Company.new(params[:company])
if @company.save
if params[:default_company]
Company.set_default_company(@company.id, current_user.id,)
end
flash[:notice] = "Company was successfully created."
redirect_to @company
else
redirect_to new_company_path
end
end
以下是我对使用类方法还是实例方法调用set_default_company
感到困惑的地方。他们似乎都会工作,我看不到其中任何一方的好处。
除了向我提供有关使用哪种方法的任何信息之外,如果有人可以向我展示一个简短的写作实现,那么作为一个类方法与实例方法,它可以让我更好地理解为什么。
以下是我写它们的方式:
def self.set_default_company(company, user)
# Logic here
end
def set_default_company(company, user)
# Logic here
end
以这种方式写作,我认为两者都没有好处。
答案 0 :(得分:15)
顾名思义,模型上的实例方法应该用于与用户的特定实例(调用该方法的实例)相关的逻辑/操作。因此,您可以考虑设置默认公司用户作为User
上的实例方法。类方法适用于不在模型的单个实例上运行的事物,或者您没有可用实例的情况。例如您可能有一个类方法来整理您的数据库,例如User.purge_expired_users
,这不适用于单个用户对象。
e.g。
class User
def set_default_company(company)
exists = DefaultCompany.find(self.id)
if exists
exists.update_attributes(company: company)
else
DefaultCompany.create(company: company, user: self)
end
end
end
然后你的控制器方法看起来像:
def create
@company = Company.new(params[:company])
if @company.save
if params[:default_company]
current_user.set_default_company @company
end
flash[:notice] = "Company was successfully created."
redirect_to @company
else
redirect_to new_company_path
end
end
或者,您可以从其他角度考虑关系,并将实例方法放在Company
上,例如company.set_as_default_for(user)
。
答案 1 :(得分:4)
我实际上会在set_default_company
上设置User
实例方法。 User
有一个默认Company
;为什么Company
需要默认的用户?
class User
def set_default_company(company)
exists = DefaultCompany.find(id)
if exists
exists.update_attributes(company: company)
else
DefaultCompany.create(company: company, user: self)
end
end
end
答案 2 :(得分:2)
在我看来,如果所讨论的方法代表在实例化的所有对象中非常通用的信息/行为,那么我总是创建一个class method
,这与我在相信时使用的instance methods
不同它更像是所讨论的实例化对象的特定操作。
但这是我的观点。
答案 3 :(得分:1)
一些事情:你有一个单独的DefaultCompany表吗?这似乎应该是公司表上的布尔标志。
接下来,公司和用户之间是否存在关联?如果是这样,那么最好的方法就是
在用户模型中
def set_default_company(company)
self.companies.each do |c|
c.update_attributes(:default => false)
end
company.update_attributes(:default => true)
end
或在公司模式中
def set_as_default
update_attributes(:default_company => true)
end