-
-
Save foxweb/485c6348e21e437862e7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The logic looks like this: | |
Already have an Invite to this "email" from current_user?: | |
If not - create a new Invite, send an email (method deliver at model) | |
If he went there more than one day ago | |
then update Invite and send a new mail AGAIN | |
otherwise, notice: "Invite has been sent. Check the spam folder or wait for another day". | |
Model Invite works OK. | |
Please, check 'create' method. It's not work right. | |
I use "find_or_create_by_email". | |
If find exists Invite, I need "save" this and notice user. | |
If create new Invite, I dont need "save", but user must be notice also! | |
How to be notice condition? How to use find_or_create withModel validation for updated_at? (validator "ensure_user_can_resend_invites") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
require 'digest/sha1' | |
class Invite < ActiveRecord::Base | |
acts_as_archive :class => 'Invite::Archive', :table => 'archived_invites' | |
USER_ORIGIN = 'user'.freeze | |
API_ORIGIN = 'api'.freeze | |
DEDUCED_USER_ORIGIN = 'deduced user'.freeze | |
SPAM_ORIGIN = 'spam'.freeze | |
QUEUE_ORIGIN = 'queue'.freeze | |
DIRECT_ORIGIN = 'direct'.freeze | |
attr_accessor :skip_email_notify | |
attr_accessor :from_partner | |
belongs_to :user | |
belongs_to :partner_link | |
belongs_to :venture | |
before_validation :set_user_from_partner, :on => :create | |
before_validation :set_free_days_count, :on => :create | |
before_validation :set_default_origin, :on => :create | |
before_validation :set_partner_link, :on => :create | |
validates :user_id, :email, :venture, :presence => true | |
validate :ensure_email_not_registered | |
validate :ensure_user_can_send_invites, :on => :create | |
validate :ensure_user_can_resend_invites, :on => :update | |
validates_as_email_address :email | |
validates :email, :uniqueness => { :scope => :user_id, :case_sensitive => false } | |
before_create :create_token | |
after_create :deliver | |
after_update :deliver | |
scope :including_partner, includes(:partner_link => [ :partner, :email_branding ]) | |
scope :from_ventures, lambda { |v_ids| | |
if v_ids.blank? | |
scoped | |
else | |
where(:venture_id => v_ids.split(',')) | |
end | |
} | |
scope :search_by, lambda { |t| | |
if t =~ /^[0-9a-f]{40}$/i | |
where('invites.token LIKE ?', "#{t}") | |
else | |
where('invites.email LIKE ? or users.email LIKE ?', "#{t}", "#{t}").includes(:user) | |
end | |
} | |
scope :created_after, lambda { |m| | |
where('invites.created_at > ?', Time.zone.at(m.to_i)) | |
} | |
scope :created_before, lambda { |m| | |
where('invites.created_at < ?', Time.zone.at(m.to_i)) | |
} | |
def deliver | |
unless skip_email_notify | |
InvitesMailer.invite(user, self).deliver | |
end | |
end | |
def to_param | |
token | |
end | |
def email=(e) | |
super(e.strip.gsub(/^</,'').gsub(/>$/,'')) | |
end | |
def new_user | |
@new_user ||= SiteUser.new do |u| | |
u.email = email | |
u.origin_kind = origin_kind | |
u.origin_details = origin_details | |
u.invite = self | |
u.partner_link = partner_link | |
u.registered_by_invitation_code = token | |
u.free_period_days = free_days_count || 0 | |
u.email_confirmed = true | |
end | |
end | |
def user_email=(v) # Stub для симметрии. | |
end | |
def user_email | |
@user_email ||= user.try(:email) | |
end | |
def as_json(options = {}) | |
options ||= {} | |
options = options.merge(:methods => [:user_email, :link], | |
:include => { :partner_link => { :include => :partner } }) | |
super(options) | |
end | |
def link | |
# XXX Bit hairy. | |
"#{partner_link.email_branding.link_site.root}/invites/#{token}" | |
end | |
protected | |
def create_token | |
loop { | |
self.token = Digest::SHA1.hexdigest("--#{Time.now}--#{rand}--") | |
break unless Invite.find_by_token(token) | |
} | |
end | |
def set_user_from_partner | |
if user.blank? && user_id.blank? && from_partner.present? | |
self.user = Partner.find_by_name(from_partner).try(:api_invites_owner) | |
self.origin_kind = API_ORIGIN | |
end | |
end | |
def set_free_days_count | |
if user | |
self.free_days_count = user.have_trusted_invites? ? 3 : 0 | |
end | |
end | |
def set_default_origin | |
if origin_kind.blank? && user | |
self.origin_kind = USER_ORIGIN | |
self.origin_details = user.login | |
end | |
end | |
def set_partner_link | |
self.partner_link = user.partner_link if user | |
self.venture = user.venture if user | |
end | |
def ensure_email_not_registered | |
errors.add(:email, :already_registered) if email && venture.users.find_by_email(email) | |
end | |
def ensure_user_can_send_invites | |
errors.add(:user, :cant_send_invites) if user && !user.can_invite_friends? | |
errors.add(:user, :email_not_confirmed) if user && !user.email_confirmed? | |
end | |
def ensure_user_can_resend_invites | |
if updated_at > 1.day.ago | |
errors.add(:email, :taken) | |
else | |
message_will_change! | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
class UserInvitesController < ApplicationController | |
skip_before_filter :verify_authenticity_token | |
before_filter :authenticate_from_pc | |
def index | |
@invite = current_user.invites.build | |
@invites = current_user.invites.all | |
@invited_users, @payed_invited_users = current_user.invited_users.all.inject [[],[]] do |arr, u| | |
u.subscription.successful_receipts_sum.blank? ? arr[0] << u : arr[1] << u | |
arr | |
end | |
end | |
def create | |
#@invite = current_user.invites.build(params[:invite]) # work if Invite new, but not update exists Invite | |
@invite = current_user.invites.find_or_create_by_email(params[:invite]) #work ok if new and if exists, but... | |
respond_to do |format| | |
if @invite.save # hmmm... if find exists - ok. if create new - save error (Invite was taken) | |
format.html { redirect_to account_invites_path, notice: "Invite was sent to #{@invite.email}" } | |
format.mobile { redirect_to account_invites_path } | |
else | |
format.html { render action: 'index' } | |
format.mobile { render action: 'index' } | |
end | |
end | |
end | |
def update | |
redirect_to account_invites_path | |
end | |
def destroy | |
@invite = Invite.find(params[:id]) | |
@invite.destroy | |
respond_to do |format| | |
format.html { redirect_to account_invites_path } | |
format.mobile { redirect_to account_invites_path } | |
end | |
end | |
protected | |
def end_of_association_chain | |
current_user.invites | |
end | |
def resource_request_name | |
:invite | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment