9

在我的 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

以这种方式写它们我也没有看到任何好处。

4

4 回答 4

20

顾名思义,模型上的实例方法应该用于与用户的特定实例(调用该方法的实例)相关的逻辑/操作。因此,您可以考虑将用户的默认公司设置为上的实例方法User。类方法适用于不对模型的单个实例进行操作的事物,或者适用于您没有可用实例的情况。例如,您可能有一个类方法来整理您的数据库,例如User.purge_expired_users它不适用于单个用户对象。

例如

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或者,您可以从另一个角度考虑关系,并在eg上放置一个实例方法company.set_as_default_for(user)

于 2012-07-25T18:05:31.577 回答
4

我实际上会set_default_companyUser. AUser有一个默认值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
于 2012-07-25T18:03:46.067 回答
2

在我看来,class method如果所讨论的方法表示在所有实例化对象中相当通用的信息/行为,我总是创建一个instance methods,与我在我认为它更像是所讨论的实例化对象的特定操作时使用的不同。

但这是我的观点。

于 2012-07-25T18:10:11.423 回答
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
于 2012-07-25T18:09:09.177 回答