Ruby on rails 在模型rails中设置嵌套属性

Ruby on rails 在模型rails中设置嵌套属性,ruby-on-rails,Ruby On Rails,我有一个属于用户和公司的日志模型。为了设置这个,我在logs\u控制器的创建操作中有这个代码 def create @log = Log.new(params[:log]) @log.user = current_user @log.firm = current_firm @log.save end 当前用户和当前公司是应用程序\u helper.rb中的助手方法 这样做的同时,会使控制器变胖。如何将其移动到模型中?没有区别:您可以重构代码: d

我有一个属于用户和公司的日志模型。为了设置这个,我在logs\u控制器的创建操作中有这个代码

 def create
     @log = Log.new(params[:log])
     @log.user = current_user
     @log.firm = current_firm
     @log.save
   end
当前用户和当前公司是应用程序\u helper.rb中的助手方法


这样做的同时,会使控制器变胖。如何将其移动到模型中?

没有区别:您可以重构代码:

def create
  @log = Log.new(params[:log].merge(:user => current_user, :firm => current_firm)
  @log.save
end
您的日志必须:

attr_accessible :user, :firm

没有区别:您可以重构代码:

def create
  @log = Log.new(params[:log].merge(:user => current_user, :firm => current_firm)
  @log.save
end
您的日志必须:

attr_accessible :user, :firm

我相信这种功能属于
lib/
中的“worker”类。我的动作方法可能看起来像

def create
  @log = LogWorker.create(params[:log], current_user, current_firm)
end
然后我在
lib/log\u worker.rb中有一个模块

module LogWorker
  extend self

  def create(params, user, firm)
    log      = Log.new(params)
    log.user = user
    log.firm = firm

    log.save
  end
end

这是一个简化的例子;我通常为所有内容命名名称空间,因此我的方法实际上可能在
MyApp::Log::Manager.create(…)
我相信这种功能属于
lib/
中的“worker”类。我的动作方法可能看起来像

def create
  @log = LogWorker.create(params[:log], current_user, current_firm)
end
然后我在
lib/log\u worker.rb中有一个模块

module LogWorker
  extend self

  def create(params, user, firm)
    log      = Log.new(params)
    log.user = user
    log.firm = firm

    log.save
  end
end

这是一个简化的例子;我通常为所有内容命名名称空间,因此我的方法实际上可能位于
MyApp::Log::Manager.create(…)

不短,但处理当前用户的责任落在MVC中的控制器身上

def create
 @log = Log.create(params[:log].merge(
   :user => current_user,
   :firm => current_firm))
end
编辑

如果您不介意稍微违反MVC,以下是一种方法:

# application_controller.rb
before_filter :set_current
def set_current
  User.current = current_user
  Firm.current = current_firm
end

# app/models/user.rb
cattr_accessor :current

# app/models/firm.rb
cattr_accessor :current

# app/models/log.rb
before_save :set_current
def set_current
  self.firm = Firm.current
  self.user = User.current
end

# app/controllers/log_controller.rb
def create
  @log = Log.create(params[:log])
end

虽然不短,但处理当前用户的责任落在MVC中的控制器身上

def create
 @log = Log.create(params[:log].merge(
   :user => current_user,
   :firm => current_firm))
end
编辑

如果您不介意稍微违反MVC,以下是一种方法:

# application_controller.rb
before_filter :set_current
def set_current
  User.current = current_user
  Firm.current = current_firm
end

# app/models/user.rb
cattr_accessor :current

# app/models/firm.rb
cattr_accessor :current

# app/models/log.rb
before_save :set_current
def set_current
  self.firm = Firm.current
  self.user = User.current
end

# app/controllers/log_controller.rb
def create
  @log = Log.create(params[:log])
end

就我个人而言,我不认为你这里有什么是脂肪,可能有很好的理由来编码它完全一样,你有。实际上,您可能希望这样做,以避免将用户和公司放在模型可访问的属性中。起初我对它很满意,但现在它变得非常好;)我同意
attr\u accessible
。我喜欢在worker类中这样做的一个原因是,它有助于强制执行创建模型实例的单个入口点,以及强制执行将设置必要的关系(尽管验证也有助于这一点;worker方法的签名有助于充当指南)。这也使得测试控制器中用于操纵模型的功能变得非常简单。就我个人而言,我不认为你这里的内容很丰富,可能有充分的理由完全按照你的方式编写代码。实际上,您可能希望这样做,以避免将用户和公司放在模型可访问的属性中。起初我对它很满意,但现在它变得非常好;)我同意
attr\u accessible
。我喜欢在worker类中这样做的一个原因是,它有助于强制执行创建模型实例的单个入口点,以及强制执行将设置必要的关系(尽管验证也有助于这一点;worker方法的签名有助于充当指南)。它还使得测试控制器中用于操纵模型的功能变得非常简单。我非常喜欢这种方法。我觉得模型和控制器有点笨拙。非常感谢。我真的很喜欢这种方法。我觉得模型和控制器有点笨拙。非常感谢。谢谢你的回答。这个问题有点简化了。我有更复杂的事情要做。我只是想把它弄出来@Lyngstad I更新了一种干净但非MVC的处理方式,如果这种代码到处都是,您可能会感兴趣谢谢您的回答。这个问题有点简化了。我有更复杂的事情要做。我只是想把它弄出来@Lyngstad I更新了一种干净但非MVC的处理方式,如果这种代码到处都是,您可能会对这种方式感兴趣