Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.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 从Rails模型中访问当前用户?_Ruby On Rails_Ruby_Model - Fatal编程技术网

Ruby on rails 从Rails模型中访问当前用户?

Ruby on rails 从Rails模型中访问当前用户?,ruby-on-rails,ruby,model,Ruby On Rails,Ruby,Model,我正在构建一个基本上遵循以下模式的开票应用程序: 用户

我正在构建一个基本上遵循以下模式的开票应用程序:

用户<客户<项目<发票

现在,为了为每个用户生成自动递增的发票号,我将其放入我的
发票
模型中:

  before_create :create_invoice_number

  def create_invoice_number
    val = @current_user.invoices.maximum(:number)
    self.number = val + 1
  end
但是,当前的用户变量似乎无法从Rails中的模型中访问


我能做些什么来解决这个问题呢?

这是由于Rails中的关注点分离,这是一个有点棘手的问题。在Rails范例中,除了直接传递的内容外,模型不应该知道任何应用程序状态,因此大多数Rails程序员会告诉您,任何需要了解当前用户的模型都是代码气味

P说,有三种方法可以做到这一点,每一个“更正确”(或者至少我会这样认为)。 首先,尝试在发票中创建与用户的关联,并将发票链接到控制器中的用户:

class InvoicesController < ApplicationController

...

def create
  @invoice = current_user.invoices.create(params[:invoice])
  ...
end
如果不起作用,请在控制器中手动执行此操作。诚然,控制器应该尽可能地精简,但由于这显然是一个应用程序级别的问题,控制器就是放置它的地方:

class InvoicesController < ApplicationController

...

def create
  @invoice = Invoice.create(params[:invoice])
  @invoice.update_attribute(:number, current_user.invoices.maximum(:number))
  ...
end
class InvoicesController

最后,如果你真的,真的想连接控制器和模型,你可以用。它们并非用于此目的,但肯定会为您完成任务。

如果您愿意,也不应该出现这种情况,然后使用rails中的
观察者
进行身份验证?通常,它们会为您提供一个类似于
current\u user
的方法,而不是一个类似于
@current\u user
的实例变量。或者您是否在某个地方手动创建
@current\u user
?如果是这样的话,你就必须把它传递出去,或者把它存储在会话变量或其他什么东西中+嘿,谢谢你的帮助。第一个版本不起作用,因为在某种程度上,
当前用户
方法无法在模型中使用。第二个版本可以工作,但对我来说有点难看,因为它会使我的控制器膨胀…第一个版本是用于控制器,而不是模型。如何使用即时加载减少查询数量?如果您将它放在控制器中,并且您正试图访问联接表,则它会对每个主对象记录执行该操作,而不是访问加载的联接记录。我只是做错了吗?你必须首先了解观察者是如何定义和工作的?@Veraticus的答案应该是满足你的需要……不要在事情实际上并不复杂的时候让事情变得复杂;)
class InvoicesController < ApplicationController

...

def create
  @invoice = Invoice.create(params[:invoice])
  @invoice.update_attribute(:number, current_user.invoices.maximum(:number))
  ...
end