0

好的,我真的很坚持这一点,提出一些想法可能会很好,这可能是一个很长的帖子。

首先让我试着解释一下我想要做什么。目前我有一个名为 Book 的模型和一个名为 Snippets 的嵌套模型。我的 Book 模型中有一个名为 size 的列,它定义了它是否为 [0 => 'Short'、1 => 'Medium'、2 => 'Long']。我的 Book 控制器中也有一个总字数,它会给我每个片段中的字数。现在我想要尝试做的是根据大小 [0,1,2] 定义不同的字数限制。下图示例

大小(内容长度验证)| 字数

每次创作短 (500) | 共20,000字

中等 (700) 每个创作 | 总共50,000字

每次创作的长 (1000) | 总共100,000字

current_word_count - total_word_count 取决于大小 [short,med,long]

因此,根据我现在正在工作的书中定义的大小,我希望该书中片段的总字数由模型定义,包括所有当前帖子,例如,如果我有一本短书并且我已经有 10,000 个字在片段中应该有 10,000 个。我之所以这样认为,是因为并非每个用户都会始终发布所需的最大值。

现在是代码。

首先是模型:

图书.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

片段.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 的新手,我只是想这样做以了解代码和您可以做的事情。

一如既往,我感谢您的帮助和反馈。

4

1 回答 1

0

啊,自定义验证,这就是我要做的:

书本.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

片段.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 
于 2013-10-21T00:27:22.443 回答