what I want to do is to let a user endorse 3 other users a month only (and perhaps clear the limit with each new month if possible.
I've tried following this ror limiting users to 2 posts per day
With no luck. I've created the this_month method in my user model
def this_month
where(:created_at => (Time.zone.now.beginning_of_month..Time.zone.now))
end
and in my Endorsements model:
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
And I get an error when trying to endorse
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'
What am I missing in here?
This is my user model
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
And endorsement controller:
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
I've cut out the unnecessary (i think) things. If needed the rest of the code (without some additions) is present at https://bitbucket.org/kramarz/pracainzynierska