Ruby on rails RubyonRails:限制用户每月认可(评论)3个其他用户

Ruby on rails RubyonRails:限制用户每月认可(评论)3个其他用户,ruby-on-rails,ruby,Ruby On Rails,Ruby,我想做的是让一个用户一个月只支持3个其他用户(如果可能的话,也许每个新的月份都会清除限制) 我已经试过了 没有运气。我已经在我的用户模型中创建了this_month方法 def this_month where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now)) end 在我的背书模式中: class Endorsement < ActiveRecord::Base belongs_to :e

我想做的是让一个用户一个月只支持3个其他用户(如果可能的话,也许每个新的月份都会清除限制)

我已经试过了

没有运气。我已经在我的用户模型中创建了this_month方法

def this_month
   where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now))
end
在我的背书模式中:

class Endorsement < ActiveRecord::Base
  belongs_to :endorser, class_name: "User"
  belongs_to :endorsed, class_name: "User"
  validates :endorser_id, presence: true
  validates :endorsed_id, presence: true
  validates :comment, presence: true, length: { maximum: 140}
  validate :endorsement_count_within_limit?, :on => :create

  private
    def endorsement_count_within_limit?
      if endorser.endorsing.this_month.count >= 3
        errors.add(:base, "Exceeded endorse limit (3) this month")
      end
    end

end
class背书:创建
私有的
def背书数量是否在限额内?
如果endorser.endoring.this_month.count>=3
错误。添加(:base,“本月超过背书限额(3))
结束
结束
结束
我在尝试背书时出错了

NoMethodError (undefined method `this_month' for #<User::ActiveRecord_Associations_CollectionProxy:0x007fe6bd957fa8>):
  app/models/endorsement.rb:11:in `endorsement_count_within_limit?'
  app/models/user.rb:113:in `endorse'
  app/controllers/endorsements_controller.rb:7:in `create'
NoMethodError(未定义的方法#的'this_month'):
app/models/approval.rb:11:in“approval\u count\u intheu limit?”
app/models/user.rb:113:in“背书”
app/controllers/endorsements\u controller.rb:7:在“创建”中
我在这里错过了什么

这是我的用户模型

class User < ActiveRecord::Base
  has_many :active_endorsements, class_name: "Endorsement",
                                 foreign_key: "endorser_id",
                                 dependent: :destroy
  has_many :passive_endorsements, class_name:  "Endorsement",
                                  foreign_key: "endorsed_id",
                                  dependent:   :destroy
.
.
.
  has_many :endorsing, through: :active_endorsements, source: :endorsed
  has_many :endorsers, through: :passive_endorsements, source: :endorser

  attr_accessor :remember_token, :activation_token, :reset_token
  before_save :downcase_email
  before_create :create_activation_digest
  validates :name, presence: true, length: { maximum: 50}
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
.
.
.

  # Endorses a user.
  def endorse(other_user, comment)
    active_endorsements.create(endorsed_id: other_user.id, comment: comment)
  end

  # Unendorses a user.
  def unendorse(other_user)
    active_endorsements.find_by(endorsed_id: other_user.id).destroy
  end

  # Returns true if the current user is endorsing the other user.
  def endorsing?(other_user)
    endorsing.include?(other_user)
  end

  def this_month
    where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now))
  end
  private

.
.
.
end
class用户(Time.zone.now.start_of_month..Time.zone.now))
结束
私有的
.
.
.
结束
和背书控制员:

class EndorsementsController < ApplicationController
  before_action :logged_in_user

  def create
    @user = User.find(params[:endorsed_id])
    comment = params[:endorsement][:comment]
    current_user.endorse(@user, comment)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end

  def destroy
    @user = Endorsement.find(params[:id]).endorsed
    current_user.unendorse(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end

end
类背书控制器

我已经删掉了不必要的(我认为)东西。如果需要,剩下的代码(没有一些附加内容)会出现在

上,看起来背书是一个集合,而不是一个单一的模型,所以它没有你在两个模型上构建的
方法

试着换成

def endorsement_count_within_limit?
  if endorser.endorsing.where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now)).count >= 3
    errors.add(:base, "Exceeded endorse limit (3) this month")
  end
end

然后看看它是否解决了这个问题。这可以通过将它定义为一个而不是一个方法来解决。我实际上找到了一个原因

在用户模型中应该是这样的:

has_many :endorsing, through: :active_endorsements, source: :endorsed do
    def this_month
      where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now))
    end
  end
我错过了另一篇文章的do..end,并将该方法放在了模型的末尾。它现在似乎可以工作了,产生了一个错误

ArgumentError (First argument in form cannot contain nil or be empty):
  app/views/shared/_unendorse.html.erb:1:in `_app_views_shared__unendorse_html_erb__1506472371249770260_70025812987440'
  app/views/endorsements/create.js.erb:1:in `_app_views_endorsements_create_js_erb__2132303159922640595_70025812908380'
  app/controllers/endorsements_controller.rb:8:in `create'
在服务器日志中。我相信这是一个有效的错误(已经有3个被认可的用户)-但是我怎么能在网站上显示它呢?所以它看起来像在方法中

“本月超出背书限额(3)”

而不是错误产生的结果

编辑:

我已成功解决了正确显示的错误:)

归结起来,在我的背书模式中有这种方法:

  def endorsement_count_within_limit?
    if endorser.endorsing.where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now)).count >= 3
      errors.add(:base, "Exceeded endorse limit (3) this month")
    end
  end
并让我的“背书部分”根据用户是否背书其他用户呈现正确的表格:

<%= form_for(current_user.active_endorsements.build, remote: true) do |f| %>
  <% if f.object.endorsement_count_within_limit? %>
    <div id="error_explanation">
      <div class="alert alert-danger">
        The form contains <%= pluralize(f.object.errors.count, "error") %>.
      </div>
      <ul>
      <% f.object.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% else %>
    <div><%= hidden_field_tag :endorsed_id, @user.id %></div>
    <%= f.submit "Endorse", class: "btn btn-primary" %>
    <%= f.text_field :comment, class: 'form-control' %>
  <% end %>
<% end %>

表单包含。

请检查我下面的答案,我可以确认这解决了问题,我下面的答案也解决了问题。不确定哪条路是“好”的道路:P但它确实解决了它,如果你能看看下面的答案,其余的问题仍然没有答案?我不确定还有哪些问题没有解决?当月份发生变化时,它会自动重置,因为该查询将不再从上一个月获取任何背书。这太愚蠢了,哈!你完全正确!非常感谢。您知道如何以一种好的方式显示错误吗?我试过几个主意,但似乎都不管用。或者我应该为此发布一个新的问题吗?如果你仍然在下面遇到这个错误,我会说至少先调试一下。查看堆栈跟踪中的这两个erb文件,查看参数为nil的位置。如果你不能弄明白,那么再发一篇帖子,确保包含那些erb文件及其相关参数