2013-10-20 128 views
0

好吧我真的很困擾這一點,它可能是很好的拋出一些想法,這可能是一個很長的帖子。根據尺寸類型定義限制

首先,讓我嘗試解釋我想要做的事情。目前我有一個叫做Book的模型,它有一個名爲Snippets的嵌套模型。我的Book模型中有一個名爲size的列,它定義它是否爲[0 =>'Short',1 =>'Medium',2 =>'Long']。我的Book控制器中還有一個總字數,它會給我每個片段的字數。現在我想嘗試和做的是取決於大小[0,1,2]定義字數不同的限制。示例如下所示

大小(內容長度驗證)|字數

每個創建的短(500)|共20000字

中創建(700)總共50,000字

每個創建的長(1000)| 10萬個字共

current_word_count - 根據大小[短,中,長期]

所以這取決於我現在的工作簿中定義的大小,我想的話的內容片斷總量total_word_count在這本書中,要根據所有當前帖子的模型進行定義,例如,如果我有一本簡短的書,並且我已經有一萬個詞已經在片段中,那麼應該剩下10,000個詞。我通過這種方式思考的原因是因爲並非每個用戶總是會發布所需的最大數量。

現在的代碼。

首先,車型:

Book.rb

class Book < ActiveRecord::Base 
    has_many :snippets 
    attr_accessible :title, :book_id, :size 


    def get_word_count 
    @word_count = 0 
    self.snippets.each.do |c| 
    @word_count += c.content.scan(/\w+/).size 
    end 

    def short? 
    size == 0 
    end 

    def medium? 
    size == 1 
    end 

    def long? 
    size == 2 
    end 
end 

Snippet.rb

class Snippet < ActiveRecord::Base 
    before_create :check_limit 
    belongs_to :book 
    attr_accessible :content, :book_id 

    validates :book_id, presence: true 
    #validates_length_of :content, less_than: 200, if: book.small? 
    #validates_length_of :content, less_than: 500, if: book.medium? 
    #validates_length_of :content, less_than: 1000, if: book.long? 


    def check_limit   
     if book.word_limit_reached? 
     errors.add :base, 'Snippet limit reached.'   
     return false 
     end  
     return true 
    end 
end 

看到,因爲這是一個數據庫的動作,我不會真的需要只需輕觸控制器直到我定義了這些規則。我一直坐在這裏嘗試各種各樣的事情,但由於我還是Rails的新手,我只是想要這樣做,讓我的頭腦圍繞代碼和你可以做的事情。

一如既往,我感謝您的幫助和反饋。

回答

0

啊,自定義驗證的善良,這是我會做什麼:

book.rb

class Book < ActiveRecord::Base 
    has_many :snippets 


    def get_word_count 
    @word_count = [] 
    self.snippets.each do |c| 
     @word_count << c.content.scan(/\w+/).size 
    end 
    @word_count = @word_count.inject(:+) 
    # Similar to what you had before, but this creates an array, and adds each 
    # content size to the array, the inject(:+) is a method done on an array to sum 
    # each element of the array, doesn't work with older versions of ruby, but it's safe 
    # 1.9.2 and up 
    end 

    def short? 
    size == 0 
    end 

    def medium? 
    size == 1 
    end 

    def long? 
    size == 2 
    end 
end 

Snippet.rb

class Snippet < ActiveRecord::Base 
    belongs_to :book 
    validate :size_limit 

    # Here I created a constant containing a hash with your book limitation parameters 
    # This way you can compare against it easily 
    BOOK_SIZE = { 
    0 => {"per" => 500, "total" => 20000}, 
    1 => {"per" => 700, "total" => 50000}, 
    2 => {"per" => 1000, "total" => 100000} 
    } 


    def size_limit 
    # Sets the book size, which is the same as the hash key for your constant BOOK_SIZE 
    book_limit = self.book.size 
    # Scans the content attribute and sets the word count 
    word_count = self.content.scan(/\w+/).size 
    # This is getting the total word count, for all the snippets and the new snippet 
    # the user wants to save 
    current_snippets_size = (self.book.get_word_count || 0) + word_count 
    # This is where your validation magic happens. There are 2 comparisons done and if they 
    # don't both pass, add an error that can be passed back to the controller. 
    # 1st If your content attribute is smaller than allowed for that particular book 
    # 2nd If your total snippets content for all previous and current snippet are less than 
    # allowed by the total book size defined in the constant 
    errors.add(:content, "Content size is too big") unless word_count < BOOK_SIZE[book_limit]['per'] && current_snippets_size < BOOK_SIZE[book_limit]['total'] 
    end 

end 
+0

老兄,你是神!這需要我花一些時間才能理解,也許你可以逐步瞭解每一行的內容,這樣我就可以掌握這些代碼,我理解它的大部分內容。 –