2012-02-22 106 views
2

我建立基本上遵循以下模式的進銷存應用:從Rails模型中訪問current_user?

Users < Clients < Projects < Invoices

以生成每個用戶我把這個在我的 Invoice模型自動遞增發票編號

現在:

before_create :create_invoice_number 

    def create_invoice_number 
    val = @current_user.invoices.maximum(:number) 
    self.number = val + 1 
    end 

但是,似乎不能從Rails中的模型中訪問current_user變量?

我能做些什麼來解決這個問題?

+0

使用observers?通常他們給你一個像'current_user'這樣的方法,而不是像'@ current_user'這樣的實例變量。或者你是否在某處手動創建'@ current_user'?如果是這樣,你必須將它傳遞或存儲在會話變量或其他東西。 – MrDanA 2012-02-22 18:10:27

回答

9

這是由於在Rails的關注點分離是一個有點艱難的問題來處理。在Rails範例中,模型除了直接傳遞任何應用程序狀態之外,不應該知道任何應用程序狀態,因此大多數Rails編碼器會告訴您,任何需要了解current_user的模型都是代碼異味。

這就是說,有三種方法可以做到這一點,每一個「更正確」(或至少我會考慮他們的話)。

首先,嘗試創建關聯的發票裏面的用戶,並在控制器中的發票鏈接到用戶:

class InvoicesController < ApplicationController 

... 

def create 
    @invoice = current_user.invoices.create(params[:invoice]) 
    ... 
end 

而在你的模型:

belongs_to :user 

def create_invoice_number 
    self.user.invoices.maximum(:number) + 1 
end 

如果沒有按」 t工作,請在控制器中手動執行此操作。這是真的,控制器應始終作爲瘦得像您可以管理,但由於這顯然是一個應用程序級的關注控制器是把它的地方:

class InvoicesController < ApplicationController 

... 

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

最後,如果你真的想彌合控制器和型號,您可以使用ActionController::Sweepers。他們不是爲此目的而設計的,但肯定會爲你完成工作。

+1

絕對地,從模型中訪問當前用戶是一種代碼異味。 +1 – 2012-02-22 18:17:38

+0

嘿,謝謝你的幫助。第一個版本不起作用,因爲'current_user'方法不能在模型中使用。第二個版本的工作,但看起來有點醜陋,因爲它膨脹了我的控制器... – Tintin81 2012-02-23 10:18:31

+0

第一個版本是打算在控制器,而不是模型。 – Veraticus 2012-02-23 15:00:04

1

不應該有任何出現這樣的情況,如果仍然想你然後做在您使用的身份驗證什麼軌

+0

你必須首先了解觀察者是如何定義和工作的? – 2012-02-24 07:24:26

+0

@Veraticus答案應該實現你想要的東西...... dnt使事情變得複雜時,他們不是真的;) – 2012-02-24 07:44:31

相關問題