Created
April 20, 2015 18:13
-
-
Save Amitesh/6503c4986c690e86a6dd to your computer and use it in GitHub Desktop.
sample-code-snippets
This file contains hidden or 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
/** | |
* Module for QHash Application | |
* @author : Amitesh Kumar | |
* | |
*/ | |
window.QHash = window.QHash || {}; | |
( function ( QHash ) { | |
/** | |
* Answer Model | |
* @param {[type]} answer [description] | |
* @return {[type]} [description] | |
*/ | |
var Answer = function(answer){ | |
answer = answer || {}; | |
this.content = answer["content"]; | |
this.id = answer["id"] || (new Date().getTime()); | |
this.is_correct = answer["is_correct"]; | |
this.order_no = answer["order_no"]; | |
this.question_id = answer["question_id"]; | |
this.updated_at = answer["updated_at"]; | |
this.created_at = answer["created_at"]; | |
this.answerType = answer["answer_type"] || 1; | |
this.isNew = !!!answer["id"]; | |
}; | |
Answer.prototype = { | |
isSingleChoice: function(){ | |
return this.answerType() == 1; | |
}, | |
isMultipleChoice: function(){ | |
return this.answerType() == 2; | |
}, | |
isSubjective: function(){ | |
return this.answerType() == 3; | |
}, | |
remove: function(){ | |
alert("removed...") | |
} | |
}; | |
/** | |
* Question handler class | |
* @return {[type]} [description] | |
*/ | |
QHash.QuestionRender = (function(){ | |
var answers = {}; | |
var answerTypeSelect = "#question_answer_type"; | |
var answerType = function(){ return $( answerTypeSelect ).val(); } | |
var answersCont; | |
return { | |
init: function(){ | |
answersCont = $("#answers") | |
this.refreshAnswers(); | |
this.initUI(); | |
}, | |
refreshAnswers: function(){ | |
answers = {}; | |
for (var i = 0; i < answers_data.length; i++) { | |
this.setAnswer(answers_data[i]); | |
}; | |
this.render(); | |
}, | |
initUI: function(){ | |
var me = this; | |
$( answerTypeSelect ).change(function(){ | |
me.render(); | |
}); | |
$(answersCont).on('change', 'input:radio', function(){ | |
$(".answer-hd", answersCont).val(false); | |
$(this).parent().find(':hidden').val( $(this).is(':checked') ? true : false ); | |
}); | |
$(answersCont).on('change', 'input:radio, input:checkbox, input:text', function(){ | |
var id = $(this).data('answer-id'); | |
var answer = answers[id]; | |
if(answer){ | |
if($(this).is(':text')){ | |
answer.content = $(this).val(); | |
}else if($(this).is(':radio')){ | |
$.each(answers, function(key, value) { | |
value.is_correct = false; | |
answers[key] = value; | |
}); | |
answer.is_correct = $(this).is(':checked') ? true : false; | |
}else{ | |
answer.is_correct = $(this).is(':checked') ? true : false; | |
} | |
answers[id] = answer; | |
} // if end | |
}); | |
$(answersCont).on('click', '.remove-answer-btn', function(event){ | |
return me.removeAnswer(event) | |
}); | |
$('.add-new-answer').on('click', function(){ | |
return me.addNewAnswer(); | |
}); | |
}, | |
setAnswer: function(answer){ | |
var ans = new Answer( answer ); | |
ans.answerType = answerType; | |
answers[ans.id] = ans; | |
}, | |
getAnswers: function(){ | |
var answrs = []; | |
$.each(answers, function(key, value) { answrs.push(value) }); | |
return answrs | |
}, | |
render: function(){ | |
var template = Handlebars.compile( $("#answer-template").html() ); | |
answersCont.html( template({answers: this.getAnswers()})); | |
$('input:radio', answersCont).each(function(){ | |
$(this).parent().find(':hidden').val($(this).is(':checked')? true : false); | |
}) | |
}, | |
addNewAnswer: function(){ | |
var ans = new Answer(); | |
ans.answerType = answerType; | |
answers[ans.id] = ans; | |
this.render(); | |
return false; | |
}, | |
removeAnswer: function(event){ | |
var me = this; | |
var elem = $(event.target); | |
var id = elem.data('answer-id'); | |
var answer = answers[id]; | |
if(answer){ | |
if(answer.isNew){ | |
delete answers[id]; | |
this.render(); | |
}else{ | |
$.post( elem.attr('href'), function() { | |
delete answers[id]; | |
me.render(); | |
}).fail(function( jqXHR, textStatus, error) { | |
// console.log( arguments ); | |
alert( jqXHR.responseJSON.error ); | |
}).always(function() { | |
}); | |
} | |
} | |
return false; | |
} | |
}; | |
})(); | |
} )( window.QHash ); |
This file contains hidden or 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
# User model | |
# == Schema Information | |
# | |
# Table name: users | |
# | |
# id :integer not null, primary key | |
# email :string(255) default(""), not null | |
# encrypted_password :string(255) default(""), not null | |
# reset_password_token :string(255) | |
# reset_password_sent_at :datetime | |
# remember_created_at :datetime | |
# sign_in_count :integer default(0), not null | |
# current_sign_in_at :datetime | |
# last_sign_in_at :datetime | |
# current_sign_in_ip :string(255) | |
# last_sign_in_ip :string(255) | |
# confirmation_token :string(255) | |
# confirmed_at :datetime | |
# confirmation_sent_at :datetime | |
# unconfirmed_email :string(255) | |
# failed_attempts :integer default(0), not null | |
# unlock_token :string(255) | |
# locked_at :datetime | |
# created_at :datetime | |
# updated_at :datetime | |
# username :text | |
# username_lowercase :text | |
# admin :boolean default(FALSE), not null | |
# show_app_caveat :boolean default(TRUE), not null | |
# apps_count :integer default(0), not null | |
# app_families_count :integer default(0), not null | |
# payments_count :integer default(0), not null | |
# | |
# A user of the app. Uses [Devise](https://github.com/plataformatec/devise) for | |
# authentication. | |
class User < ActiveRecord::Base | |
# 1. Configuration | |
devise :database_authenticatable, :registerable, :recoverable, :rememberable, | |
:trackable, :validatable, :timeoutable, :confirmable | |
include FriendlyId | |
friendly_id :username_lowercase | |
# 2. Attributes | |
# @private | |
attr_accessor :login | |
attr_readonly :username_lowercase | |
def to_s; username; end | |
def has_unidentified_apps? | |
# Filter out any unidentified apps which have no app identifiers. There | |
# shouldn't be any anyway, but stay on the safe side, because if they do | |
# find their way into the DB, the user will receive the 'you have orphaned | |
# data' message, but won't be able to do anything about it. | |
self.apps.unidentified.select { |a| a.app_identifiers.any? }.any? | |
end | |
# Note regarding show_app_caveat: This boolean determines whether the 'app | |
# caveat' notification should be displayed on an app's show page. It's true | |
# when the user is first created, then they set it to false by clicking | |
# "don't show this again". This is a very simple implementation and is NOT a | |
# good idea if the app grows to the point where users have lots of | |
# dismissable notifications. I'm doing it this way for now just because | |
# there's only one notification for the time being so it's not worth the | |
# effort of a more complicated system. | |
# 3. Validations | |
VALID_USERNAME_REGEX ||= /\A[A-Za-z][A-Za-z0-9_]*\z/ | |
DISALLOWED_USERNAMES ||= YAML::load_file("config/disallowed_names.yml") | |
validates_presence_of :username | |
validates :username, uniqueness: { case_sensitive: false }, | |
length: { minimum: 5, maximum: 20 }, | |
format: { | |
with: VALID_USERNAME_REGEX, | |
message: "can only contain letters, numbers and underscores" | |
}, :if => "self.username.present?" | |
validate :username_cant_be_a_reserved_word, :if => "self.username?" | |
# 4. Associations | |
include User::PaymentAssociations | |
has_many :app_families, dependent: :destroy | |
has_many :apps, dependent: :destroy | |
has_many :app_problems, through: :apps, source: :problems, | |
:class_name => Diagnostics::AppProblem | |
has_many :metric_time_slices, through: :apps | |
has_many :app_identifiers, through: :apps, dependent: :destroy | |
has_many :connections, dependent: :destroy | |
has_many :data_sources, through: :connections | |
has_many :ad_networks, -> { merge(DataSource.ad_networks) }, through: :connections, source: :data_source | |
has_many :marketplaces, -> { merge(DataSource.marketplaces) }, through: :connections, source: :data_source | |
# @param data_source [DataSource] a data source. | |
# @return [Boolean] whether the user has added credentials for the given data | |
# source. | |
def connected_to?(data_source) | |
data_sources.include?(data_source) | |
end | |
# The user's apps which aren't connected to a specified data source. Used | |
# to identify unidentified apps. A user might have not yet identified one | |
# of their apps for a particular data source. When we receive unidentified data | |
# for that data source, we want to know which apps don't already have an | |
# identifier for that data source, because the unidentified data might belong | |
# to one of them. | |
# | |
# @option opts [DataSource] :data_source A data source. (required) | |
# @return [ActiveRecord::Relation<App>] All of the user's apps which are **a)** | |
# not unidentified and **b)** don't already have an `AppIdentifier` connecting | |
# them to the given data source. | |
def mergeable_apps(opts={}) | |
data_source = opts.fetch(:data_source) | |
data_source.apps.missing.where(user_id: self.id).identified | |
# Note that this first attempt doesn't work: | |
# | |
# self.apps.includes(:data_sources).identified | |
# .where.not(app_identifiers: { data_source_id: data_source.id }) | |
# | |
# because if an app is connected to ANY data_source other than the given one | |
# , then the condition `data_source.id != (excluded data source).id` will | |
# be true for that row of the left outer join, so the app will be returned | |
# even if it's not connected to the specified data source. | |
end | |
# 5. Scopes | |
# 6. Callbacks | |
before_save { |u| u.username = u.username.downcase } | |
before_save { |u| u.username_lowercase = u.username.downcase } | |
# Override the Devise method so that Users can log in using either their | |
# email or username. goo.gl/yXDJd3 | |
def self.find_first_by_auth_conditions(warden_conditions) | |
conditions = warden_conditions.dup | |
if login = conditions.delete(:login) | |
where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first | |
else | |
where(conditions).first | |
end | |
end | |
def to_param | |
self.username.downcase | |
end | |
private | |
# Can't use validates_exclusion_of because it needs to be case-insensitive | |
def username_cant_be_a_reserved_word | |
if DISALLOWED_USERNAMES.include? self.username.downcase | |
errors[:username] << "is not an allowed username" | |
end | |
end | |
end |
This file contains hidden or 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
# == Schema Information | |
# | |
# Table name: users | |
# | |
# id :integer not null, primary key | |
# email :string(255) default(""), not null | |
# encrypted_password :string(255) default(""), not null | |
# reset_password_token :string(255) | |
# reset_password_sent_at :datetime | |
# remember_created_at :datetime | |
# sign_in_count :integer default(0), not null | |
# current_sign_in_at :datetime | |
# last_sign_in_at :datetime | |
# current_sign_in_ip :string(255) | |
# last_sign_in_ip :string(255) | |
# confirmation_token :string(255) | |
# confirmed_at :datetime | |
# confirmation_sent_at :datetime | |
# unconfirmed_email :string(255) | |
# failed_attempts :integer default(0), not null | |
# unlock_token :string(255) | |
# locked_at :datetime | |
# created_at :datetime | |
# updated_at :datetime | |
# username :text | |
# username_lowercase :text | |
# admin :boolean default(FALSE), not null | |
# show_app_caveat :boolean default(TRUE), not null | |
# apps_count :integer default(0), not null | |
# app_families_count :integer default(0), not null | |
# payments_count :integer default(0), not null | |
# | |
require 'spec_helper' | |
describe User do | |
let(:email) { "[email protected]" } | |
let(:pw) { "foobar123" } | |
let(:username) { "ExampleUser"} | |
let(:user) do | |
User.new(email: email, | |
password: pw, | |
password_confirmation: pw, | |
username: username | |
) | |
end | |
subject { user } | |
# 1. Configuration | |
# 2. Attributes | |
it { should have_readonly_attribute :username_lowercase } | |
describe "#paid?" do | |
before { user.save! } | |
# Reload user so that it registers the update to payments_count | |
subject { user.reload.paid? } | |
context "when user has no Payments" do | |
it { should be_false } | |
end | |
context "when user's most recent payment" do | |
before { create(:payment, user: user, date: date) } | |
context "is more than than 1 month + Payment::GRACE_PERIOD ago" do | |
let(:date) { Payment.cutoff_date - 1.day } | |
it { should be_false } | |
end | |
context "is less than than 1 month + Payments::GRACE_PERIOD ago" do | |
let(:date) { Payment.cutoff_date + 1.day } | |
it { should be_true } | |
end | |
end | |
end | |
describe "#date_of_most_recent_payment" do | |
subject { user.date_of_most_recent_payment } | |
context "when the user" do | |
context "has no payments" do | |
it { should be_nil } | |
end | |
context "has payments" do | |
before do | |
user.save! | |
create(:payment, user: user, date: "2014-05-02") | |
create(:payment, user: user, date: "2014-05-01") | |
end | |
it "returns the date of the most recent payment" do | |
expect(subject).to eq Date.parse("2014-05-02") | |
end | |
end | |
end | |
end | |
# 3. Validations | |
it { should validate_uniqueness_of(:username).case_insensitive } | |
it { should validate_presence_of(:username) } | |
it do | |
disallowed_usernames = YAML::load_file("config/disallowed_names.yml") | |
should ensure_exclusion_of(:username).\ | |
in_array(disallowed_usernames).with_message("is not an allowed username") | |
end | |
it { should ensure_length_of(:username).is_at_least(5).is_at_most(20) } | |
it do | |
should allow_value( | |
"john", "john1234", "abcdefghijklmnop" | |
).for(:username) | |
end | |
it do | |
should_not allow_value( | |
"shrt", "long5678901234568901", "3startswithnumber", "specialchar!" | |
).for(:username) | |
end | |
it { should be_valid } | |
# 4. Associations | |
it { should have_many(:apps).dependent(:destroy) } | |
it { should have_many(:app_problems).through(:apps) } | |
it { should have_many(:app_families).dependent(:destroy) } | |
it { should have_many(:data_sources) } | |
it { should have_many(:connections).dependent(:destroy) } | |
it { should have_many(:app_families) } | |
it { should have_many(:app_identifiers) } | |
it { should have_many(:marketplaces) } | |
it { should have_many(:ad_networks) } | |
it { should have_many(:payments).dependent(:destroy) } | |
describe "#connected_to?(data_source)" do | |
let(:ds) { create(:data_source) } | |
before { user.save! } | |
subject { user.connected_to?(ds) } | |
context "when the user is connected to the data source" do | |
it "returns true" do | |
user.connections.create(data_source: ds, credential_1: "xxxx") | |
should be_true | |
end | |
end | |
context "when the user is not connected to the data source" do | |
it "returns false" do | |
should be_false | |
end | |
end | |
end | |
# 5. Scopes | |
# 6. Callbacks | |
describe "username_lowercase" do | |
it "is set to username.downcase before save" do | |
user.save! | |
expect(user.username_lowercase).to eq username.downcase | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment