Thrift module: tutorial
The first thing to know about are types. The available types in Thrift are:
bool Boolean, one byte
i8 (byte) Signed 8-bit integer
i16 Signed 16-bit integer
i32 Signed 32-bit integer
i64 Signed 64-bit integer
double 64-bit floating point value
string String
binary Blob (byte array)
map<t1,t2> Map from one type to another
list<t1> Ordered list of one type
set<t1> Set of unique elements of one type
Did you also notice that Thrift supports C style comments?
Constants
| Constant | Type | Value |
INT32CONSTANT | i32 | 9853 |
Thrift also lets you define constants for use across languages. Complex
types and structs are specified using JSON notation.
|
MAPCONSTANT | map<string , string > | { "hello" = "world", "goodnight" = "moon" } |
Enumerations
Enumeration: Operation
You can define enums, which are just 32 bit integers. Values are optional
and start at 1 if not supplied, C style again.
ADD | 1 |
|
SUBTRACT | 2 |
|
MULTIPLY | 3 |
|
DIVIDE | 4 |
|
Type declarations
Typedef: MyInteger
Base type: i32
Thrift lets you do typedefs to get pretty names for your types. Standard
C style here.
Data structures
Struct: Work
| Key | Field | Type | Description | Requiredness | Default value |
| 1 | num1 | i32 | | default | 0 |
| 2 | num2 | i32 | | default | |
| 3 | op | Operation | | default | |
| 4 | comment | string | | optional | |
Structs are the basic complex data structures. They are comprised of fields
which each have an integer identifier, a type, a symbolic name, and an
optional default value.
Fields can be declared "optional", which ensures they will not be included
in the serialized output if they aren't set. Note that this requires some
manual management in some languages.
Exception: InvalidOperation
| Key | Field | Type | Description | Requiredness | Default value |
| 1 | whatOp | i32 | | default | |
| 2 | why | string | | default | |
Structs can also be exceptions, if they are nasty.
Services
Service: Calculator
Ahh, now onto the cool part, defining a service. Services just need a name
and can optionally inherit from another service using the extends keyword.
Function: Calculator.ping
void
ping()
A method definition looks like C code. It has a return type, arguments,
and optionally a list of exceptions that it may throw. Note that argument
lists and exception lists are specified using the exact same syntax as
field lists in struct or exception definitions.
Function: Calculator.add
i32
add(i32
num1,
i32
num2)
Function: Calculator.zip
void
zip()
This method has a oneway modifier. That means the client only makes
a request and does not listen for any response at all. Oneway methods
must be void.


CLERKS A film review by Joan Ellis Copyright 1996 Nebbadoon Syndicate
Listen up, world: "Clerks" is a landmark movie, and you will remember you saw it in 1994. Kevin Smith, writer, producer, director, editor, and actor, is writing in a new language that represents not only the arrival of a new generation, but also a profound change in the world of movies.
Smith's "Clerks" and Quentin Tarantino's "Pulp Fiction" have appeared back to back, a double-feature exemplifying the creative explosion of the video culture so many of us have misunderstood. Here, then, is the flip side of the conventional wisdom that watching too much TV dulls the mind.
Both movies are driven by dialogue born in the minds of men who have soaked up the rhythms of the video screen. Using a vocabulary of classic four-letter words not as epithets but as natural conversation, Smith and Tarantino are saying that this is the way people talk. If obscenities used to imply a kind of mental poverty, a literary laziness, they now mean comfortable, easy exchange.
Kevin Smith raised $27,000 to make a movie about two convenience-store clerks on his home turf of Leonardo, NJ, and walked away with major awards at the Cannes and Sundance film festivals. His movie chronicles, in excruciating detail, the nothingness of one day in the life of the lethargic Dante Hicks (Brian O'Halloran), who wakes up on his day off to discover no one is running the store.
Arriving grumpily at the Quick Stop, he steps into his daily routine and lets the world happen to him. His drifty and outrageously funny friend, Randall (Jeff Anderson), needles him relentlessly to grab control of his life. Alas, poor Dante. A guy who says, "That's what high school is about: algebra, bad lunch and infidelity," is not likely to be touched by the pressures of duty, drive, or goals.
These two spend the day laid out on the floor talking about girls, hockey, nudie booths, and nothing while selling cigarettes and coffee to anyone unlucky enough to cross their slothful paths. They comment on the passing parade of "women who check the dates looking for milk that won't go bad for a decade" and "guys who check every egg to get a perfect dozen."
If you can suspend your disbelief and surrender to the feel of the thing, you will see a very funny, gentle movie played by a group of perfect slackers.
Ten years ago, video schmoozing was a new sport. At least two of the kids transfixed by it grew up to be video clerks, absorbing B-movie dialogue while missing the picture as they waited on customers. What stayed in their heads were words, not images. Kevin Smith and Quentin Tarantino have absorbed the rhythms of their time, and they are going to teach them to the rest of us. They have done no less than announce the birth of a new language and a new way of making movies.
Film Critic: JOAN ELLIS Word Count: 498 Studio: Miramax Rating: R 1h30m
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


for batch in valid_iter:
src, src_lengths = inputters.make_features(batch, "src")
tgt, _ = inputters.make_features(batch, "tgt")
// F-prop through the model.
outputs, attns = self.model(src, tgt, src_lengths)
stats = onmt.utils.Statistics()
for batch in valid_iter:
src, src_lengths = batch.src if isinstance(batch.src, tuple) \
else (batch.src, None)
tgt = batch.tgt
// F-prop through the model.
outputs, attns = self.model(src, tgt, src_lengths)


personal website : html5 , css3 , javascript and bootstrap 4 coded within 48hrs
it was a challenge that i took to just proof i am being a good frontend dev by the day.
test qualification assignment : html5 , pure css3, javascript coded for 1 week
it was test just to for me to get a motive to move into backend dev and start to work with server side languages from my mentor. (@emmanuelr20)
my personal backend project although unfinished : html5 , pure css3, javascript , PHP and Mysqli
it just a project am working on just to be working on my backend programming skill, which the project consist of different categories like, Admin and just app user . Admin can perfom the CRUD operation blocked account of user search trough users and so on while the the users can login, logout , register and the CRUD as well.
NOTE: CRUD stand for CREATE , READ , UPDATE , DELETE.


Generative Adversarial Networks (GAN)¶
This demo implements GAN training described in the original GAN paper and deep convolutional generative adversarial networks DCGAN paper.
The high-level structure of GAN is shown in Figure. 1 below. It is composed of two major parts: a generator and a discriminator, both of which are based on neural networks. The generator takes in some kind of noise with a known distribution and transforms it into an image. The discriminator takes in an image and determines whether it is artificially generated by the generator or a real image. So the generator and the discriminator are in a competitive game in which generator is trying to generate image to look as real as possible to fool the discriminator, while the discriminator is trying to distinguish between real and fake images.
Figure 1. GAN-Model-Structure figure credit
The generator and discriminator take turn to be trained using SGD. The objective function of the generator is for its generated images being classified as real by the discriminator, and the objective function of the discriminator is to correctly classify real and fake images. When the GAN model is trained to converge to the equilibrium state, the generator will transform the given noise distribution to the distribution of real images, and the discriminator will not be able to distinguish between real and fake images at all.
Implementation of GAN Model Structure¶
Since GAN model involves multiple neural networks, it requires to use paddle python API. So the code walk-through below can also partially serve as an introduction to the usage of Paddle Python API.
There are three networks defined in gan_conf.py, namely generator_training, discriminator_training and generator. The relationship to the model structure we defined above is that discriminator_training is the discriminator, generator is the generator, and the generator_training combined the generator and discriminator since training generator would require the discriminator to provide loss function. This relationship is described in the following code:
if is_generator_training:
noise = data_layer(name="noise", size=noise_dim)
sample = generator(noise)
if is_discriminator_training:
sample = data_layer(name="sample", size=sample_dim)
if is_generator_training or is_discriminator_training:
label = data_layer(name="label", size=1)
prob = discriminator(sample)
cost = cross_entropy(input=prob, label=label)
classification_error_evaluator(
input=prob, label=label, name=mode + '_error')
outputs(cost)
if is_generator:
noise = data_layer(name="noise", size=noise_dim)
outputs(generator(noise))
In order to train the networks defined in gan_conf.py, one first needs to initialize a Paddle environment, parse the config, create GradientMachine from the config and create trainer from GradientMachine as done in the code chunk below:
import py_paddle.swig_paddle as api
# init paddle environment
api.initPaddle('--use_gpu=' + use_gpu, '--dot_period=10',
'--log_period=100', '--gpu_id=' + args.gpu_id,
'--save_dir=' + "./%s_params/" % data_source)
# Parse config
gen_conf = parse_config(conf, "mode=generator_training,data=" + data_source)
dis_conf = parse_config(conf, "mode=discriminator_training,data=" + data_source)
generator_conf = parse_config(conf, "mode=generator,data=" + data_source)
# Create GradientMachine
dis_training_machine = api.GradientMachine.createFromConfigProto(
dis_conf.model_config)
gen_training_machine = api.GradientMachine.createFromConfigProto(
gen_conf.model_config)
generator_machine = api.GradientMachine.createFromConfigProto(
generator_conf.model_config)
# Create trainer
dis_trainer = api.Trainer.create(dis_conf, dis_training_machine)
gen_trainer = api.Trainer.create(gen_conf, gen_training_machine)
In order to balance the strength between generator and discriminator, we schedule to train whichever one is performing worse by comparing their loss function value. The loss function value can be calculated by a forward pass through the GradientMachine.
def get_training_loss(training_machine, inputs):
outputs = api.Arguments.createArguments(0)
training_machine.forward(inputs, outputs, api.PASS_TEST)
loss = outputs.getSlotValue(0).copyToNumpyMat()
return numpy.mean(loss)
After training one network, one needs to sync the new parameters to the other networks. The code below demonstrates one example of such use case:
# Train the gen_training
gen_trainer.trainOneDataBatch(batch_size, data_batch_gen)
# Copy the parameters from gen_training to dis_training and generator
copy_shared_parameters(gen_training_machine,
dis_training_machine)
copy_shared_parameters(gen_training_machine, generator_machine)
A Toy Example¶
With the infrastructure explained above, we can now walk you through a toy example of generating two dimensional uniform distribution using 10 dimensional Gaussian noise.
The Gaussian noises are generated using the code below:
def get_noise(batch_size, noise_dim):
return numpy.random.normal(size=(batch_size, noise_dim)).astype('float32')
The real samples (2-D uniform) are generated using the code below:
# synthesize 2-D uniform data in gan_trainer.py:114
def load_uniform_data():
data = numpy.random.rand(1000000, 2).astype('float32')
return data
The generator and discriminator network are built using fully-connected layer and batch_norm layer, and are defined in gan_conf.py.
To train the GAN model, one can use the command below. The flag -d specifies the training data (cifar, mnist or uniform) and flag –useGpu specifies whether to use gpu for training (0 is cpu, 1 is gpu).
$python gan_trainer.py -d uniform --useGpu 1
The generated samples can be found in ./uniform_samples/ and one example is shown below as Figure 2. One can see that it roughly recovers the 2D uniform distribution.
Figure 2. Uniform Sample
MNIST Example¶
Data preparation¶
To download the MNIST data, one can use the following commands:
$cd data/
$./get_mnist_data.sh
Model description¶
Following the DC-Gan paper (https://arxiv.org/abs/1511.06434), we use convolution/convolution-transpose layer in the discriminator/generator network to better deal with images. The details of the network structures are defined in gan_conf_image.py.
Training the model¶
To train the GAN model on mnist data, one can use the following command:
$python gan_trainer.py -d mnist --useGpu 1
The generated sample images can be found at ./mnist_samples/ and one example is shown below as Figure 3.
Figure 3. MNIST Sample


The following sequence diagrams describe in detail the different scenarios involved in the
setup and teardown of peer connections. Before going through them, it helps to keep the
following things in mind:
1. A peer consists of PeerConnectionClient (PCC) which manages communication with the SigninServer (SS), and one each of PeerConnectionObserver (PO) and PeerConnection (PC) to manage a voice connection with one other remote peer.
2. PO acts as a liason between PC and PCC, and is responsible for creating/destroying PC, forwarding signaling messages meant for the remote peer to PCC, and forwarding replies from the remote peer to PC.
3. There are two diagrams for each scenario. The first one describes just the sequence of events in the scenario between just the elements involved in the peer connection. The second one describes the sequence of events with the involvement of PCC and SS. The purpose of having two sequence diagrams for each scenario is to show a clear demarcation between the peer-to-peer and the signaling aspects of setting up a peer connection. WebRTC is intended to manage only the peer-to-peer media connection, and what signaling protocol to use for call setup/teardown is left to the discretion of the developer.
1. A peer consists of PeerConnectionClient (PCC) which manages communication with the SigninServer (SS), and one each of PeerConnectionObserver (PO) and PeerConnection (PC) to manage a voice connection with one other remote peer.
2. PO acts as a liason between PC and PCC, and is responsible for creating/destroying PC, forwarding signaling messages meant for the remote peer to PCC, and forwarding replies from the remote peer to PC.
3. There are two diagrams for each scenario. The first one describes just the sequence of events in the scenario between just the elements involved in the peer connection. The second one describes the sequence of events with the involvement of PCC and SS. The purpose of having two sequence diagrams for each scenario is to show a clear demarcation between the peer-to-peer and the signaling aspects of setting up a peer connection. WebRTC is intended to manage only the peer-to-peer media connection, and what signaling protocol to use for call setup/teardown is left to the discretion of the developer.


We always focus on Features that customers needs.This is an example description.Company is the Future


Index
All Classes|All Packages
G
- Genre - Enum in musichub.business
- GERMAN - musichub.business.Language
- getAlbums() - Method in class musichub.server.MusicHubServer
- getAlbumSongs(String) - Method in class musichub.business.MusicHub
-
Create a string of the list of songs in a album.
- getAlbumSongsSortedByGenre(String) - Method in class musichub.business.MusicHub
-
Create a string of the list of songs in a album, sorted by genre.
- getAlbumsTitlesSortedByDate() - Method in class musichub.business.MusicHub
-
Create a string of the list of albums, sorted by date.
- getArtist() - Method in class musichub.business.AudioElement
- getAudiobooksTitlesSortedByAuthor() - Method in class musichub.business.MusicHub
-
Create a string of the list of audiobooks, sorted by author.
- getAudioElementByName(String) - Method in class musichub.business.MusicHub
-
Return an audio element from the list by its name.
- getAudioElements() - Method in class musichub.server.MusicHubServer
- getAudioFile(AudioElement) - Method in class musichub.business.ServerConnection
-
Request an audio file from the server, open a new file in the tmp/audio folder with its UUID as name, write it and close it.
- getCategory() - Method in class musichub.business.AudioBook
- getCategory() - Method in enum musichub.business.Category
- getContent() - Method in class musichub.business.AudioElement
- getDate() - Method in class musichub.business.Album
- getElements() - Method in class musichub.business.PlayList
- getFormat() - Method in class musichub.business.AudioElement
- getFormat() - Method in enum musichub.business.Format
- getGenre() - Method in enum musichub.business.Genre
- getGenre() - Method in class musichub.business.Song
- getLanguage() - Method in class musichub.business.AudioBook
- getLanguage() - Method in enum musichub.business.Language
- getName() - Method in class musichub.business.AudioInputStreamCache
- getPlaylists() - Method in class musichub.server.MusicHubServer
- getSongs() - Method in class musichub.business.Album
- getSongsRandomly() - Method in class musichub.business.Album
- getStream() - Method in class musichub.business.AudioInputStreamCache
- getStreamFile(String) - Method in class musichub.util.FileStreamHandler
- getTitle() - Method in class musichub.business.Album
- getTitle() - Method in class musichub.business.AudioElement
- getTitle() - Method in class musichub.business.PlayList
- getUUID() - Method in class musichub.business.AudioElement
- getUuidByName(String) - Method in class musichub.business.MusicHub
-
Return the Uuid of an audio element by its name.
All Classes|All Packages


Follow these steps if you have a dispute with your neighbour.
- Try to solve the problem informally by talking to them.

- Use a mediation service if raising the issue informally doesn’t work.

- Take legal action through the courts as a last resort.


View Trainee Page
Trainee's Information
Search:
Trainee ID
First Name
Surname
Email
Contact Number
Date Of Birth
Gender
Start Date
Trainee ID
First Name
Surname
Email
Contact Number
Date Of Birth
Gender
Start Date


{% extends "bootstrap/base.html" %} {% block title %}This is foo-d{% endblock %} {% block styles -%} {{super()}} {% endblock styles %} {% block content %}
Enter your postcode to find your nearest places to eat.
| Place | Distance (m) |
|---|---|
| {{item[0]}} | {{item[1]}} |


The Authenticator Certification Levels introduce Authenticator Security Requirements to the FIDO Certification Program. Authenticators must be certified to at least Authenticator Certification Level 1 (L1) for UAF, U2F, and FIDO2 certification. Currently, the supported Cert...


{% import "forms/form_macros.jinja" as form %} {% extends "forms/base/creation_form.html" %} {% set page_title = 'Create New Aggregate' %} {% block content %}


All Files (89.46% covered at 1.84 hits/line)
41 files in total.
408 relevant lines.
365 lines covered and
43 lines missed
# frozen_string_literal: true
- 1
ActiveAdmin.register Admin do
- 1
permit_params :email, :username, :password, :password_confirmation
- 1
index do
- 1
selectable_column
- 1
id_column
- 1
column :email
- 1
column :username
- 1
column :current_sign_in_at
- 1
column :sign_in_count
- 1
column :created_at
- 1
actions
end
- 1
filter :email
- 1
filter :current_sign_in_at
- 1
filter :sign_in_count
- 1
filter :created_at
- 1
form do |f|
f.inputs do
f.input :email
f.input :username
f.input :password
f.input :password_confirmation
end
f.actions
end
end
# frozen_string_literal: true
- 1
ActiveAdmin.register_page 'Dashboard' do
- 12
menu priority: 1, label: proc { I18n.t('active_admin.dashboard') }
- 17
content title: proc { I18n.t('active_admin.dashboard') } do
- 8
div class: 'blank_slate_container', id: 'dashboard_default_message' do
- 8
span class: 'blank_slate' do
- 8
span I18n.t('active_admin.dashboard_welcome.welcome')
- 8
small I18n.t('active_admin.dashboard_welcome.call_to_action')
end
end
end
end
# frozen_string_literal: true
- 1
ActiveAdmin.register Product do
- 1
permit_params :name, :cost, :country_of_origin
- 1
index do
- 1
selectable_column
- 1
id_column
- 1
column :name
- 1
column :cost
- 1
column :country_of_origin
- 1
actions
end
end
# frozen_string_literal: true
- 1
ActiveAdmin.register Review do
- 1
permit_params :author, :content_body, :rating
- 1
index do
selectable_column
id_column
column :author
column :content_body
column :rating
actions
end
end
# frozen_string_literal: true
- 1
ActiveAdmin.register User do
- 1
permit_params :email, :username, :password, :password_confirmation
- 1
index do
- 1
selectable_column
- 1
id_column
- 1
column :email
- 1
column :username
- 1
column :current_sign_in_at
- 1
column :sign_in_count
- 1
column :created_at
- 1
actions
end
end
# frozen_string_literal: true
- 1
module ApplicationCable
- 1
class Channel < ActionCable::Channel::Base
end
end
# frozen_string_literal: true
- 1
module ApplicationCable
- 1
class Connection < ActionCable::Connection::Base
end
end
# frozen_string_literal: true
- 1
class ApplicationController < ActionController::Base
- 1
before_action :configure_permitted_parameters, if: :devise_controller?
- 1
def authorize_admin_user
- 2
if !current_user && !current_admin
flash[:alert] = "You aren't authorized to visit that page."
redirect_back(fallback_location: root_path)
end
end
- 1
protected
- 1
def configure_permitted_parameters
- 16
devise_parameter_sanitizer.permit(:sign_up,
keys: %i[username email password password_confirmation])
- 16
devise_parameter_sanitizer.permit(:sign_in,
keys: %i[login password password_confirmation])
- 16
devise_parameter_sanitizer.permit(:account_update,
keys: %i[username email password_confirmation current_password])
end
end
# frozen_string_literal: true
- 1
class ProductsController < ApplicationController
- 1
before_action :authenticate_admin!, except: %i[index show]
- 1
before_action :set_product, only: %i[show edit update destroy]
- 1
def index
- 10
@top_product = Product.most_reviewed.first
- 10
@product_search = Product.where("name ilike '%#{params[:search]}%'").uniq
- 10
@products = Product.all
- 10
@page_products = Kaminari.paginate_array(@products).page(params[:page]).per(10)
- 10
render :index
end
- 1
def new
- 5
@product = Product.new
- 5
render :new
end
- 1
def create
- 5
@product = Product.new(product_params)
- 5
if @product.save
- 4
flash[:notice] = 'Product successfully added!'
- 4
redirect_to products_path
else
- 1
flash[:alert] = 'Error adding product'
- 1
render :new
end
end
- 1
def edit
- 1
render :edit
end
- 1
def show
- 4
render :show
end
- 1
def update
- 1
if @product.update(product_params)
- 1
flash[:notice] = 'Product successfully updated!'
- 1
redirect_to products_path
else
flash[:alert] = 'Error updating product'
render :edit
end
end
- 1
def destroy
- 1
if @product.destroy
- 1
flash[:notice] = 'Product successfully deleted!'
else
flash[:alert] = 'Error deleting product'
end
- 1
redirect_to products_path
end
- 1
private
- 1
def product_params
- 6
params.require(:product).permit(:name, :cost, :country_of_origin)
end
- 1
def set_product
- 7
@product = Product.find(params[:id])
end
end
# frozen_string_literal: true
- 1
class ReviewsController < ApplicationController
- 1
before_action :authorize_admin_user, only: %i[new create]
- 1
before_action :authenticate_admin!, only: %i[edit destroy]
- 1
before_action :set_product, except: %i[update destroy]
- 1
before_action :set_review, only: %i[show edit update destroy]
- 1
def new
- 1
@product = Product.find(params[:product_id])
- 1
@review = @product.reviews.new
- 1
render :new
end
- 1
def create
- 1
@product = Product.find(params[:product_id])
- 1
@review = @product.reviews.new(review_params)
- 1
if @review.save
- 1
flash[:notice] = 'Review successfully added!'
- 1
redirect_to product_path(@product)
else
flash[:alert] = 'Error adding review'
render :new
end
end
- 1
def edit
@product = Product.find(params[:product_id])
@review = Review.find(params[:id])
render :edit
end
- 1
def show
@product = Product.find(params[:product_id])
@review = Review.find(params[:id])
render :show
end
- 1
def update
@review = Review.find(params[:id])
if @review.update(review_params)
redirect_to<EMAIL_ADDRESS>else
render :edit
end
end
- 1
def destroy
@review = Review.find(params[:id])
@review.destroy
redirect_to reviews_path
end
- 1
private
- 1
def review_params
- 1
params.require(:review).permit(:author, :content_body, :rating)
end
- 1
def set_product
- 2
@product = Product.find(params[:product_id])
end
- 1
def set_review
@review = Review.find(params[:id])
end
end
# frozen_string_literal: true
- 1
class StaticController < ApplicationController
- 1
def index
@top_product = Product.most_reviewed.first
@product_search = Product.where("name ilike '%#{params[:search]}%'").uniq
@products = Product.all
render :index
end
end
# frozen_string_literal: true
- 1
module ApplicationHelper
end
# frozen_string_literal: true
- 1
module StaticHelper
end
# frozen_string_literal: true
- 1
class ApplicationJob < ActiveJob::Base
end
# frozen_string_literal: true
- 1
class ApplicationMailer < ActionMailer::Base
- 1
default from<EMAIL_ADDRESS>- 1
layout 'mailer'
end
# frozen_string_literal: true
- 1
class Admin < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
- 1
devise :database_authenticatable,
:recoverable, :rememberable, :validatable
- 1
attr_accessor :login
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
- 1
devise :database_authenticatable,
:recoverable, :rememberable, :validatable, authentication_keys: [:login]
- 1
def login
- 88
@login || username || email
end
- 1
def self.find_for_database_authentication(warden_condition)
- 8
conditions = warden_condition.dup
- 8
login = conditions.delete(:login)
- 8
where(conditions).where(
['lower(username) = :value OR lower(email) = :value',
{ value: login.strip.downcase }]
).first
end
- 1
def validate_username
errors.add(:username, :invalid) if Admin.where(email: username).exists?
end
- 1
validates :username, presence: :true, uniqueness: { case_sensitive: false }
end
# frozen_string_literal: true
- 1
class ApplicationRecord < ActiveRecord::Base
- 1
self.abstract_class = true
end
# frozen_string_literal: true
- 1
class Product < ApplicationRecord
- 1
scope :most_reviewed, lambda {
- 10
select('products.*, count(reviews.id) as reviews_count')
.joins(:reviews)
.group('products.id')
.order('reviews_count DESC')
.limit(1)
}
- 21
scope :usa, -> { where("country_of_origin ilike 'Usa'").or(Product.where("country_of_origin ilike '%united states%'")) }
- 1
scope :recent_products, -> { order(created_at: :desc).limit(3) }
- 1
before_save(:titleize_product, :titleize_country)
- 1
has_many :reviews, dependent: :destroy
- 1
validates :name, :cost, :country_of_origin, presence: true
- 1
private
- 1
def titleize_product
- 14
self.name = name.titleize
end
- 1
def titleize_country
- 14
self.country_of_origin = country_of_origin.titleize
end
end
# frozen_string_literal: true
- 1
class Review < ApplicationRecord
- 1
belongs_to :product
- 1
validates :author, presence: true
- 1
validates :content_body, length: { maximum: 250, minumum: 50 }, presence: true
- 1
validates :rating, numericality: { greater_than: 0, less_than_or_equal_to: 5 }, presence: true
end
# frozen_string_literal: true
- 1
class User < ApplicationRecord
- 1
attr_accessor :login
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
- 1
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, authentication_keys: [:login]
- 1
def login
@login || username || email
end
- 1
def self.find_for_database_authentication(warden_condition)
conditions = warden_condition.dup
login = conditions.delete(:login)
where(conditions).where(
['lower(username) = :value OR lower(email) = :value',
{ value: login.strip.downcase }]
).first
end
- 1
def validate_username
errors.add(:username, :invalid) if User.where(email: username).exists?
end
- 1
validates :username, presence: :true, uniqueness: { case_sensitive: false }
end
# frozen_string_literal: true
- 1
require_relative 'boot'
- 1
require 'rails'
# Pick the frameworks you want:
- 1
require 'active_model/railtie'
- 1
require 'active_job/railtie'
- 1
require 'active_record/railtie'
- 1
require 'active_storage/engine'
- 1
require 'action_controller/railtie'
- 1
require 'action_mailer/railtie'
- 1
require 'action_view/railtie'
- 1
require 'action_cable/engine'
- 1
require 'sprockets/railtie'
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
- 1
Bundler.require(*Rails.groups)
- 1
module SpecialFoods
- 1
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
- 1
config.load_defaults 5.2
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
# Don't generate system test files.
- 1
config.generators.system_tests = nil
end
end
# frozen_string_literal: true
- 1
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
- 1
require 'bundler/setup' # Set up gems listed in the Gemfile.
- 1
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
# frozen_string_literal: true
# Load the Rails application.
- 1
require_relative 'application'
# Initialize the Rails application.
- 1
Rails.application.initialize!
# frozen_string_literal: true
- 1
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
- 1
config.cache_classes = true
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
- 1
config.eager_load = true
# Configure public file server for tests with Cache-Control for performance.
- 1
config.public_file_server.enabled = true
- 1
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
}
# Show full error reports and disable caching.
- 1
config.consider_all_requests_local = true
- 1
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates.
- 1
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
- 1
config.action_controller.allow_forgery_protection = false
# Store uploaded files on the local file system in a temporary directory
- 1
config.active_storage.service = :test
- 1
config.action_mailer.perform_caching = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
- 1
config.action_mailer.delivery_method = :test
# Print deprecation notices to the stderr.
- 1
config.active_support.deprecation = :stderr
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
# frozen_string_literal: true
- 1
ActiveAdmin.setup do |config|
# == Site Title
#
# Set the title that is displayed on the main layout
# for each of the active admin pages.
#
- 1
config.site_title = 'Special Foods'
# Set the link url for the title. For example, to take
# users to your main site. Defaults to no link.
#
# config.site_title_link = "/"
# Set an optional image to be displayed for the header
# instead of a string (overrides :site_title)
#
# Note: Aim for an image that's 21px high so it fits in the header.
#
# config.site_title_image = "logo.png"
# == Default Namespace
#
# Set the default namespace each administration resource
# will be added to.
#
# eg:
# config.default_namespace = :hello_world
#
# This will create resources in the HelloWorld module and
# will namespace routes to /hello_world/*
#
# To set no namespace by default, use:
# config.default_namespace = false
#
# Default:
# config.default_namespace = :admin
#
# You can customize the settings for each namespace by using
# a namespace block. For example, to change the site title
# within a namespace:
#
# config.namespace :admin do |admin|
# admin.site_title = "Custom Admin Title"
# end
#
# This will ONLY change the title for the admin section. Other
# namespaces will continue to use the main "site_title" configuration.
# == User Authentication
#
# Active Admin will automatically call an authentication
# method in a before filter of all controller actions to
# ensure that there is a currently logged in admin user.
#
# This setting changes the method which Active Admin calls
# within the application controller.
- 1
config.authentication_method = :authenticate_admin!
# == User Authorization
#
# Active Admin will automatically call an authorization
# method in a before filter of all controller actions to
# ensure that there is a user with proper rights. You can use
# CanCanAdapter or make your own. Please refer to documentation.
# config.authorization_adapter = ActiveAdmin::CanCanAdapter
# In case you prefer Pundit over other solutions you can here pass
# the name of default policy class. This policy will be used in every
# case when Pundit is unable to find suitable policy.
# config.pundit_default_policy = "MyDefaultPunditPolicy"
# If you wish to maintain a separate set of Pundit policies for admin
# resources, you may set a namespace here that Pundit will search
# within when looking for a resource's policy.
# config.pundit_policy_namespace = :admin
# You can customize your CanCan Ability class name here.
# config.cancan_ability_class = "Ability"
# You can specify a method to be called on unauthorized access.
# This is necessary in order to prevent a redirect loop which happens
# because, by default, user gets redirected to Dashboard. If user
# doesn't have access to Dashboard, he'll end up in a redirect loop.
# Method provided here should be defined in application_controller.rb.
# config.on_unauthorized_access = :access_denied
# == Current User
#
# Active Admin will associate actions with the current
# user performing them.
#
# This setting changes the method which Active Admin calls
# (within the application controller) to return the currently logged in user.
- 1
config.current_user_method = :current_admin
# == Logging Out
#
# Active Admin displays a logout link on each screen. These
# settings configure the location and method used for the link.
#
# This setting changes the path where the link points to. If it's
# a string, the strings is used as the path. If it's a Symbol, we
# will call the method to return the path.
#
# Default:
- 1
config.logout_link_path = :destroy_admin_session_path
# This setting changes the http method used when rendering the
# link. For example :get, :delete, :put, etc..
#
# Default:
# config.logout_link_method = :get
# == Root
#
# Set the action to call for the root path. You can set different
# roots for each namespace.
#
# Default:
# config.root_to = 'dashboard#index'
# == Admin Comments
#
# This allows your users to comment on any resource registered with Active Admin.
#
# You can completely disable comments:
# config.comments = false
#
# You can change the name under which comments are registered:
# config.comments_registration_name = 'AdminComment'
#
# You can change the order for the comments and you can change the column
# to be used for ordering:
# config.comments_order = 'created_at ASC'
#
# You can disable the menu item for the comments index page:
# config.comments_menu = false
#
# You can customize the comment menu:
# config.comments_menu = { parent: 'Admin', priority: 1 }
# == Batch Actions
#
# Enable and disable Batch Actions
#
- 1
config.batch_actions = true
# == Controller Filters
#
# You can add before, after and around filters to all of your
# Active Admin resources and pages from here.
#
# config.before_action :do_something_awesome
# == Attribute Filters
#
# You can exclude possibly sensitive model attributes from being displayed,
# added to forms, or exported by default by ActiveAdmin
#
- 1
config.filter_attributes = %i[encrypted_password password password_confirmation]
# == Localize Date/Time Format
#
# Set the localize format to display dates and times.
# To understand how to localize your app with I18n, read more at
# https://guides.rubyonrails.org/i18n.html
#
# You can run `bin/rails runner 'puts I18n.t("date.formats")'` to see the
# available formats in your application.
#
- 1
config.localize_format = :long
# == Setting a Favicon
#
# config.favicon = 'favicon.ico'
# == Meta Tags
#
# Add additional meta tags to the head element of active admin pages.
#
# Add tags to all pages logged in users see:
# config.meta_tags = { author: 'My Company' }
# By default, sign up/sign in/recover password pages are excluded
# from showing up in search engine results by adding a robots meta
# tag. You can reset the hash of meta tags included in logged out
# pages:
# config.meta_tags_for_logged_out_pages = {}
# == Removing Breadcrumbs
#
# Breadcrumbs are enabled by default. You can customize them for individual
# resources or you can disable them globally from here.
#
# config.breadcrumb = false
# == Create Another Checkbox
#
# Create another checkbox is disabled by default. You can customize it for individual
# resources or you can enable them globally from here.
#
# config.create_another = true
# == Register Stylesheets & Javascripts
#
# We recommend using the built in Active Admin layout and loading
# up your own stylesheets / javascripts to customize the look
# and feel.
#
# To load a stylesheet:
# config.register_stylesheet 'my_stylesheet.css'
#
# You can provide an options hash for more control, which is passed along to stylesheet_link_tag():
# config.register_stylesheet 'my_print_stylesheet.css', media: :print
#
# To load a javascript file:
# config.register_javascript 'my_javascript.js'
# == CSV options
#
# Set the CSV builder separator
# config.csv_options = { col_sep: ';' }
#
# Force the use of quotes
# config.csv_options = { force_quotes: true }
# == Menu System
#
# You can add a navigation menu to be used in your application, or configure a provided menu
#
# To change the default utility navigation to show a link to your website & a logout btn
#
# config.namespace :admin do |admin|
# admin.build_menu :utility_navigation do |menu|
# menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
# admin.add_logout_button_to_menu menu
# end
# end
#
# If you wanted to add a static menu item to the default menu provided:
#
# config.namespace :admin do |admin|
# admin.build_menu :default do |menu|
# menu.add label: "Home", url: "/", html_options: { target: :blank }
# end
# end
# == Download Links
#
# You can disable download links on resource listing pages,
# or customize the formats shown per namespace/globally
#
# To disable/customize for the :admin namespace:
#
# config.namespace :admin do |admin|
#
# # Disable the links entirely
# admin.download_links = false
#
# # Only show XML & PDF options
# admin.download_links = [:xml, :pdf]
#
# # Enable/disable the links based on block
# # (for example, with cancan)
# admin.download_links = proc { can?(:view_download_links) }
#
# end
# == Pagination
#
# Pagination is enabled by default for all resources.
# You can control the default per page count for all resources here.
#
# config.default_per_page = 30
#
# You can control the max per page count too.
#
# config.max_per_page = 10_000
# == Filters
#
# By default the index screen includes a "Filters" sidebar on the right
# hand side with a filter for each attribute of the registered model.
# You can enable or disable them for all resources here.
#
# config.filters = true
#
# By default the filters include associations in a select, which means
# that every record will be loaded for each association (up
# to the value of config.maximum_association_filter_arity).
# You can enabled or disable the inclusion
# of those filters by default here.
#
# config.include_default_association_filters = true
# config.maximum_association_filter_arity = 256 # default value of :unlimited will change to 256 in a future version
# config.filter_columns_for_large_association, [
# :display_name,
# :full_name,
# :name,
# :username,
# :login,
# :title,
# :email,
# ]
# config.filter_method_for_large_association, '_starts_with'
# == Head
#
# You can add your own content to the site head like analytics. Make sure
# you only pass content you trust.
#
# config.head = ''.html_safe
# == Footer
#
# By default, the footer shows the current Active Admin version. You can
# override the content of the footer here.
#
# config.footer = 'my custom footer text'
# == Sorting
#
# By default ActiveAdmin::OrderClause is used for sorting logic
# You can inherit it with own class and inject it for all resources
#
# config.order_clause = MyOrderClause
end
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# ActiveSupport::Reloader.to_prepare do
# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
# )
# end
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
- 1
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Add Yarn node_modules folder to the asset load path.
- 1
Rails.application.config.assets.paths << Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Define an application-wide content security policy
# For further information see the following documentation
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
# Rails.application.config.content_security_policy do |policy|
# policy.default_src :self, :https
# policy.font_src :self, :https, :data
# policy.img_src :self, :https, :data
# policy.object_src :none
# policy.script_src :self, :https
# policy.style_src :self, :https
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
# end
# If you are using UJS then enable automatic nonce generation
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
# Rails.application.config.content_security_policy_report_only = true
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Specify a serializer for the signed and encrypted cookie jars.
# Valid options are :json, :marshal, and :hybrid.
- 1
Rails.application.config.action_dispatch.cookies_serializer = :json
# frozen_string_literal: true
# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
- 1
Devise.setup do |config|
# The secret key used by Devise. Devise uses this key to generate
# random tokens. Changing this key will render invalid all existing
# confirmation, reset password and unlock tokens in the database.
# Devise will use the `secret_key_base` as its `secret_key`
# by default. You can change it below and use your own secret key.
# config.secret_key = 'f14bf842615ec0c8f3fa8e82660cd3a356fe81a404ea1085ea208bc779dbd91985850bf89e161d4361ed702c57974fa99ec481e0d7ecf2b052da83904809ac6d'
# ==> Controller configuration
# Configure the parent class to the devise controllers.
# config.parent_controller = 'DeviseController'
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
- 1
config.mailer_sender =<EMAIL_ADDRESS># Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'
# Configure the parent class responsible to send e-mails.
# config.parent_mailer = 'ActionMailer::Base'
# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default) and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
- 1
require 'devise/orm/active_record'
# ==> Configuration for any authentication mechanism
# Configure which keys are used when authenticating a user. The default is
# just :email. You can configure it to use [:username, :subdomain], so for
# authenticating a user, both parameters are required. Remember that those
# parameters are used only when authenticating and not when retrieving from
# session. If you need permissions, you should implement that in a before filter.
# You can also supply a hash where the value is a boolean determining whether
# or not authentication should be aborted when the value is not present.
# config.authentication_keys = [:email]
- 1
config.authentication_keys = [:login]
# Configure parameters from the request object used for authentication. Each entry
# given should be a request method and it will automatically be passed to the
# find_for_authentication method and considered in your model lookup. For instance,
# if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
# The same considerations mentioned for authentication_keys also apply to request_keys.
# config.request_keys = []
# Configure which authentication keys should be case-insensitive.
# These keys will be downcased upon creating or modifying a user and when used
# to authenticate or find a user. Default is :email.
- 1
config.case_insensitive_keys = [:email]
# Configure which authentication keys should have whitespace stripped.
# These keys will have whitespace before and after removed upon creating or
# modifying a user and when used to authenticate or find a user. Default is :email.
- 1
config.strip_whitespace_keys = [:email]
# Tell if authentication through request.params is enabled. True by default.
# It can be set to an array that will enable params authentication only for the
# given strategies, for example, `config.params_authenticatable = [:database]` will
# enable it only for database (email + password) authentication.
# config.params_authenticatable = true
# Tell if authentication through HTTP Auth is enabled. False by default.
# It can be set to an array that will enable http authentication only for the
# given strategies, for example, `config.http_authenticatable = [:database]` will
# enable it only for database authentication. The supported strategies are:
# :database = Support basic authentication with authentication key + password
# config.http_authenticatable = false
# If 401 status code should be returned for AJAX requests. True by default.
# config.http_authenticatable_on_xhr = true
# The realm used in Http Basic Authentication. 'Application' by default.
# config.http_authentication_realm = 'Application'
# It will change confirmation, password recovery and other workflows
# to behave the same regardless if the e-mail provided was right or wrong.
# Does not affect registerable.
# config.paranoid = true
# By default Devise will store the user in session. You can skip storage for
# particular strategies by setting this option.
# Notice that if you are skipping storage for all authentication paths, you
# may want to disable generating routes to Devise's sessions controller by
# passing skip: :sessions to `devise_for` in your config/routes.rb
- 1
config.skip_session_storage = [:http_auth]
# By default, Devise cleans up the CSRF token on authentication to
# avoid CSRF token fixation attacks. This means that, when using AJAX
# requests for sign in and sign up, you need to get a new CSRF token
# from the server. You can disable this option at your own risk.
# config.clean_up_csrf_token_on_authentication = true
# When false, Devise will not attempt to reload routes on eager load.
# This can reduce the time taken to boot the app but if your application
# requires the Devise mappings to be loaded during boot time the application
# won't boot properly.
# config.reload_routes = true
# ==> Configuration for :database_authenticatable
# For bcrypt, this is the cost for hashing the password and defaults to 11. If
# using other algorithms, it sets how many times you want the password to be hashed.
#
# Limiting the stretches to just one in testing will increase the performance of
# your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
# a value less than 10 in other environments. Note that, for bcrypt (the default
# algorithm), the cost increases exponentially with the number of stretches (e.g.
# a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
- 1
config.stretches = Rails.env.test? ? 1 : 11
# Set up a pepper to generate the hashed password.
# config.pepper = '593f9637396b5794bf3323098fe3e1d09e19d9697cdfab4edd829f2142ed9a67faa7b7da21845f1dcc8432c566137dd06f11242fd04f2dd0eb69c9b05f70f94f'
# Send a notification to the original email when the user's email is changed.
# config.send_email_changed_notification = false
# Send a notification email when the user's password is changed.
# config.send_password_change_notification = false
# ==> Configuration for :confirmable
# A period that the user is allowed to access the website even without
# confirming their account. For instance, if set to 2.days, the user will be
# able to access the website for two days without confirming their account,
# access will be blocked just in the third day.
# You can also set it to nil, which will allow the user to access the website
# without confirming their account.
# Default is 0.days, meaning the user cannot access the website without
# confirming their account.
# config.allow_unconfirmed_access_for = 2.days
# A period that the user is allowed to confirm their account before their
# token becomes invalid. For example, if set to 3.days, the user can confirm
# their account within 3 days after the mail was sent, but on the fourth day
# their account can't be confirmed with the token any more.
# Default is nil, meaning there is no restriction on how long a user can take
# before confirming their account.
# config.confirm_within = 3.days
# If true, requires any email changes to be confirmed (exactly the same way as
# initial account confirmation) to be applied. Requires additional unconfirmed_email
# db field (see migrations). Until confirmed, new email is stored in
# unconfirmed_email column, and copied to email column on successful confirmation.
- 1
config.reconfirmable = true
# Defines which key will be used when confirming an account
# config.confirmation_keys = [:email]
# ==> Configuration for :rememberable
# The time the user will be remembered without asking for credentials again.
# config.remember_for = 2.weeks
# Invalidates all the remember me tokens when the user signs out.
- 1
config.expire_all_remember_me_on_sign_out = true
# If true, extends the user's remember period when remembered via cookie.
# config.extend_remember_period = false
# Options to be passed to the created cookie. For instance, you can set
# secure: true in order to force SSL only cookies.
# config.rememberable_options = {}
# ==> Configuration for :validatable
# Range for password length.
- 1
config.password_length = 6..128
# Email regex used to validate email formats. It simply asserts that
# one (and only one) @ exists in the given string. This is mainly
# to give user feedback and not to assert the e-mail validity.
- 1
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
# ==> Configuration for :timeoutable
# The time you want to timeout the user session without activity. After this
# time the user will be asked for credentials again. Default is 30 minutes.
# config.timeout_in = 30.minutes
# ==> Configuration for :lockable
# Defines which strategy will be used to lock an account.
# :failed_attempts = Locks an account after a number of failed attempts to sign in.
# :none = No lock strategy. You should handle locking by yourself.
# config.lock_strategy = :failed_attempts
# Defines which key will be used when locking and unlocking an account
# config.unlock_keys = [:email]
# Defines which strategy will be used to unlock an account.
# :email = Sends an unlock link to the user email
# :time = Re-enables login after a certain amount of time (see :unlock_in below)
# :both = Enables both strategies
# :none = No unlock strategy. You should handle unlocking by yourself.
# config.unlock_strategy = :both
# Number of authentication tries before locking an account if lock_strategy
# is failed attempts.
# config.maximum_attempts = 20
# Time interval to unlock the account if :time is enabled as unlock_strategy.
# config.unlock_in = 1.hour
# Warn on the last attempt before the account is locked.
# config.last_attempt_warning = true
# ==> Configuration for :recoverable
#
# Defines which key will be used when recovering the password for an account
# config.reset_password_keys = [:email]
# Time interval you can reset your password with a reset password key.
# Don't put a too small interval or your users won't have the time to
# change their passwords.
- 1
config.reset_password_within = 6.hours
# When set to false, does not sign a user in automatically after their password is
# reset. Defaults to true, so a user is signed in automatically after a reset.
# config.sign_in_after_reset_password = true
# ==> Configuration for :encryptable
# Allow you to use another hashing or encryption algorithm besides bcrypt (default).
# You can use :sha1, :sha512 or algorithms from others authentication tools as
# :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20
# for default behavior) and :restful_authentication_sha1 (then you should set
# stretches to 10, and copy REST_AUTH_SITE_KEY to pepper).
#
# Require the `devise-encryptable` gem when using anything other than bcrypt
# config.encryptor = :sha512
# ==> Scopes configuration
# Turn scoped views on. Before rendering "sessions/new", it will first check for
# "users/sessions/new". It's turned off by default because it's slower if you
# are using only default views.
- 1
config.scoped_views = true
# Configure the default scope given to Warden. By default it's the first
# devise role declared in your routes (usually :user).
# config.default_scope = :user
# Set this configuration to false if you want /users/sign_out to sign out
# only the current scope. By default, Devise signs out all scopes.
# config.sign_out_all_scopes = true
# ==> Navigation configuration
# Lists the formats that should be treated as navigational. Formats like
# :html, should redirect to the sign in page when the user does not have
# access, but formats like :xml or :json, should return 401.
#
# If you have any extra navigational formats, like :iphone or :mobile, you
# should add them to the navigational formats lists.
#
# The "*/*" below is required to match Internet Explorer requests.
# config.navigational_formats = ['*/*', :html]
# The default HTTP method used to sign out a resource. Default is :delete.
- 1
config.sign_out_via = :delete
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
# ==> Warden configuration
# If you want to use other strategies, that are not supported by Devise, or
# change the failure app, you can configure them inside the config.warden block.
#
# config.warden do |manager|
# manager.intercept_401 = false
# manager.default_strategies(scope: :user).unshift :some_external_strategy
# end
# ==> Mountable engine configurations
# When using Devise inside an engine, let's call it `MyEngine`, and this engine
# is mountable, there are some extra configurations to be taken into account.
# The following options are available, assuming the engine is mounted as:
#
# mount MyEngine, at: '/my_engine'
#
# The router that invoked `devise_for`, in the example above, would be:
# config.router_name = :my_engine
#
# When using OmniAuth, Devise cannot automatically set OmniAuth path,
# so you need to do it manually. For the users scope, it would be:
# config.omniauth_path_prefix = '/my_engine/users/auth'
# ==> Turbolinks configuration
# If your app is using Turbolinks, Turbolinks::Controller needs to be included to make redirection work correctly:
#
# ActiveSupport.on_load(:devise_failure_app) do
# include Turbolinks::Controller
# end
# ==> Configuration for :registerable
# When set to false, does not sign a user in automatically after their password is
# changed. Defaults to true, so a user is signed in automatically after changing a password.
# config.sign_in_after_change_password = true
end
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Configure sensitive parameters which will be filtered from the log file.
- 1
Rails.application.config.filter_parameters += [:password]
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym 'RESTful'
# end
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
- 1
ActiveSupport.on_load(:action_controller) do
- 1
wrap_parameters format: [:json]
end
# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
# self.include_root_in_json = true
# end
# frozen_string_literal: true
- 1
Rails.application.routes.draw do
- 1
devise_for :admins, ActiveAdmin::Devise.config
- 1
ActiveAdmin.routes(self)
- 1
devise_for :users
- 1
root to: 'static#index'
- 1
resources :products do
- 1
resources :reviews
end
- 1
get '/admin_page' => 'admin#users'
- 1
get '/edit_user/:id' => 'admin#edit_user'
end
# frozen_string_literal: true
- 1
FactoryBot.define do
- 1
factory :admin do
end
end
# frozen_string_literal: true
- 1
FactoryBot.define do
- 1
factory :user do
end
end
# frozen_string_literal: true
- 1
require 'rails_helper'
- 1
describe 'the add,delete, and edit a product process' do
- 1
Admin.delete_all
- 1
User.delete_all
- 1
Product.delete_all
- 1
Admin.create!(username: 'admin', email<EMAIL_ADDRESS>password: 'password', password_confirmation: 'password')
- 1
Product.create(name: 'test', cost: 22.22, country_of_origin: 'usa')
- 1
User.create!(username: 'user', email<EMAIL_ADDRESS>password: 'password', password_confirmation: 'password')
- 1
before(:each) do
- 8
visit new_admin_session_path
- 8
fill_in 'admin[login]', with: 'admin'
- 8
fill_in 'admin[password]', with: 'password'
- 8
click_on 'Login'
end
- 1
it 'adds a new product' do
- 1
visit products_path
- 1
click_link 'New Product'
- 1
fill_in 'product[name]', with: 'teeth'
- 1
fill_in 'product[cost]', with: '32.27'
- 1
fill_in 'product[country_of_origin]', with: 'usa'
- 1
click_on 'Submit'
- 1
expect(page).to have_content 'Product successfully added!'
- 1
expect(page).to have_content 'Teeth'
end
- 1
it 'gives an error when no name is entered' do
- 1
visit new_product_path
- 1
click_on 'Submit'
- 1
expect(page).to have_content "Name can't be blank"
end
- 1
it 'updates product' do
- 1
visit products_path
- 1
click_link 'New Product'
- 1
fill_in 'product[name]', with: 'teeth'
- 1
fill_in 'product[cost]', with: '32.27'
- 1
fill_in 'product[country_of_origin]', with: 'turkey'
- 1
click_on 'Submit'
- 1
click_on 'Teeth'
- 1
click_on 'Edit'
- 1
fill_in 'product[name]', with: 'hair'
- 1
click_on 'Submit'
- 1
expect(page).to have_content 'Hair'
end
- 1
it 'deletes product' do
- 1
visit products_path
- 1
click_link 'New Product'
- 1
fill_in 'product[name]', with: 'teeth'
- 1
fill_in 'product[cost]', with: '32.27'
- 1
fill_in 'product[country_of_origin]', with: 'turkey'
- 1
click_on 'Submit'
- 1
click_on 'Teeth'
- 1
click_on 'Delete'
- 1
expect(page).not_to have_content 'Teeth'
end
- 1
it 'adds a new product' do
- 1
visit products_path
- 1
click_link 'New Product'
- 1
fill_in 'product[name]', with: 'teeth'
- 1
fill_in 'product[cost]', with: '32.27'
- 1
fill_in 'product[country_of_origin]', with: 'turkey'
- 1
click_on 'Submit'
- 1
click_on 'Teeth'
- 1
click_on 'Add a review'
- 1
fill_in 'review[content_body]', with: 'wow'
- 1
fill_in 'review[rating]', with: '3'
- 1
click_on 'Submit'
- 1
expect(page).to have_content 'admin'
end
- 1
it 'varifies user creation from admin' do
- 1
visit admin_users_path
- 1
expect(page).to have_content 'user'
- 1
expect(page).to have_content<EMAIL_ADDRESS>end
- 1
it 'varifies admin creation from admin' do
- 1
visit admin_admins_path
- 1
expect(page).to have_content 'admin'
- 1
expect(page).to have_content<EMAIL_ADDRESS>end
- 1
it 'varifies product listing from admin console' do
- 1
visit admin_products_path
- 1
expect(page).to have_content 'Test'
- 1
expect(page).to have_content '22.22'
- 1
expect(page).to have_content 'Usa'
end
end
# frozen_string_literal: true
- 1
require 'rails_helper'
- 1
describe Product do
- 1
context 'validations' do
- 2
it { should validate_presence_of :name }
- 2
it { should validate_presence_of :cost }
- 2
it { should validate_presence_of :country_of_origin }
- 2
it { should have_many(:reviews) }
end
- 1
context '#destroy' do
- 1
it 'should delete product' do
- 1
product = Product.create(name: 'pie', cost: '33.33', country_of_origin: 'usa')
- 2
expect { product.destroy }.to change(Product, :count).by(-1)
end
end
- 1
context '#create' do
- 1
it 'should create a new product' do
- 1
product = Product.create(name: 'pie', cost: '33.33', country_of_origin: 'usa')
- 1
expect(Product.all).to include(product)
end
end
- 1
context '#update' do
- 1
it 'should update product' do
- 1
product = Product.create(name: 'pie', cost: '33.33', country_of_origin: 'usa')
- 1
product.update(name: 'cheese', cost: '33.33', country_of_origin: 'usa')
- 1
expect(product.name).to eq('Cheese')
end
end
- 1
it('titleizes the name of an product') do
- 1
product = Product.create(name: 'pie', cost: '33.33', country_of_origin: 'usa')
- 1
expect(product.name).to eq('Pie')
end
end
# frozen_string_literal: true
- 1
require 'rails_helper'
- 1
describe Review do
- 1
context 'validations' do
- 2
it { should validate_presence_of :author }
- 2
it { should validate_presence_of :content_body }
- 2
it { should validate_length_of :content_body }
- 2
it { should validate_presence_of :rating }
- 2
it { should validate_numericality_of :rating }
end
- 2
it { should belong_to(:product) }
- 1
context '#destroy' do
- 1
it 'should delete review' do
- 1
product = Product.create(name: 'pie', cost: '33.33', country_of_origin: 'usa')
- 1
review = product.reviews.create(author: 'steve', content_body: 'wow!', rating: 5)
- 2
expect { review.destroy }.to change(Review, :count).by(-1)
end
end
- 1
context '#create' do
- 1
it 'should create a new review' do
- 1
product = Product.create(name: 'pie', cost: '33.33', country_of_origin: 'usa')
- 1
review = product.reviews.create(author: 'steve', content_body: 'wow!', rating: 5)
- 1
expect(product.reviews.all).to include(review)
end
end
- 1
context '#update' do
- 1
it 'should update review' do
- 1
product = Product.create(name: 'pie', cost: '33.33', country_of_origin: 'usa')
- 1
review = product.reviews.create(author: 'steve', content_body: 'wow!', rating: 5)
- 1
review.update(author: 'jim', content_body: 'wow!', rating: 5)
- 1
expect(review.author).to eq('jim')
end
end
end


import {TreeModule,TreeNode} from 'primeng/primeng';
Tree component requires an array of TreeNode objects as its value. Let's begin with the TreeNode api. Note that all of the properties are optional.
| Name | Type | Default | Description |
|---|---|---|---|
| label | string | null | Label of the node. |
| data | any | null | Data represented by the node. |
| icon | string | null | Icon of the node to display next to content. |
| expandedIcon | string | null | Icon to use in expanded state. |
| collapsedIcon | string | null | Icon to use in collapsed state. |
| children | TreeNode[] | null | An array of treenodes as children. |
| leaf | boolean | null | Specifies if the node has children. Used in lazy loading. |
| style | string | null | Inline style of the node. |
| styleClass | string | null | Style class of the node. |
| expanded | boolean | null | Whether the node is in an expanded or collapsed state. |
| type | string | null | Type of the node to match ng-template type. |
| parent | TreeNode | null | Parent of the node. |
| styleClass | string | null | Name of the style class for the node element. |
| draggable | boolean | null | Whether to disable dragging for a particular node even if draggableNodes is enabled. |
| droppable | boolean | null | Whether to disable dropping for a particular node even if droppableNodes is enabled. |
| selectable | boolean | null | Used to disable selection of a particular node. |
Most of the time, nodes will be loaded from a remote datasoure, here is an example NodeService that fetches the data from a json file.
@Injectable()
export class NodeService {
constructor(private http: Http) {}
getFiles() {
return this.http.get('showcase/resources/data/files.json')
.toPromise()
.then(res => <TreeNode[]> res.json().data);
}
}
The files.json file consists of sample data. In a real application, this should be a dynamic response generated from the remote call.
{
"data":
[
{
"label": "Documents",
"data": "Documents Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [{
"label": "Work",
"data": "Work Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [{"label": "Expenses.doc", "icon": "fa-file-word-o", "data": "Expenses Document"}, {"label": "Resume.doc", "icon": "fa-file-word-o", "data": "Resume Document"}]
},
{
"label": "Home",
"data": "Home Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [{"label": "Invoices.txt", "icon": "fa-file-word-o", "data": "Invoices for this month"}]
}]
},
{
"label": "Pictures",
"data": "Pictures Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [
{"label": "barcelona.jpg", "icon": "fa-file-image-o", "data": "Barcelona Photo"},
{"label": "logo.jpg", "icon": "fa-file-image-o", "data": "PrimeFaces Logo"},
{"label": "primeui.png", "icon": "fa-file-image-o", "data": "PrimeUI Logo"}]
},
{
"label": "Movies",
"data": "Movies Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [{
"label": "Al Pacino",
"data": "Pacino Movies",
"children": [{"label": "Scarface", "icon": "fa-file-video-o", "data": "Scarface Movie"}, {"label": "Serpico", "icon": "fa-file-video-o", "data": "Serpico Movie"}]
},
{
"label": "Robert De Niro",
"data": "De Niro Movies",
"children": [{"label": "Goodfellas", "icon": "fa-file-video-o", "data": "Goodfellas Movie"}, {"label": "Untouchables", "icon": "fa-file-video-o", "data": "Untouchables Movie"}]
}]
}
]
}
The component that uses this service makes a call to getFiles() and assigns them back to files property that is bound to the tree.
export class TreeDemoComponent implements OnInit {
files: TreeNode[];
constructor(private nodeService: NodeService) {}
ngOnInit() {
this.nodeService.getFiles().then(files => this.files = files);
}
}

Tree supports 3 selection methods, single, multiple and checkbox. Selection is enabled by setting selectionMode property and providing a single TreeNode or an array of TreeNodes to reference the selections depending on the selection mode.
export class TreeDemoComponent implements OnInit {
files: TreeNode[];
selectedFile: TreeNode;
constructor(private nodeService: NodeService) {}
ngOnInit() {
this.nodeService.getFiles().then(files => this.files = files);
}
}

In multiple mode or checkbox mode, selection property should be an array. In multiple mode, items can either be selected using metaKey or toggled individually depending on the value of metaKeySelection property value which is true by default. On touch enabled devices metaKeySelection is turned off automatically. In checkbox mode, when inititing a tree with preselections, also set partialSelected property on node so that minus icon can be displayed when necessary.
export class TreeDemoComponent implements OnInit {
files: TreeNode[];
selectedFiles: TreeNode[];
constructor(private nodeService: NodeService) {}
ngOnInit() {
this.nodeService.getFiles().then(files => this.files = files);
}
}

In checkbox mode, selections propagate up and down, if you prefer not to do so, propagation can be turned off by propagateSelectionDown and propagateSelectionUp properties.

Tree provides onNodeSelect and onNodeUnselect options as callbacks for selection feature.

export class TreeDemoComponent implements OnInit {
files: TreeNode[];
selectedFiles: TreeNode[];
constructor(private nodeService: NodeService) {}
ngOnInit() {
this.nodeService.getFiles().then(files => this.files = files);
}
nodeSelect(event) {
//event.node = selected node
}
}
Selection of a particular node can be disabled by setting the selectable property of the node to false.
Icon of a treenode is defined using the icon property, if you need an icon depending on the expand or collapse state, use expandedIcon and collapsedIcon instead.
By default label of a treenode is displayed inside a tree node, in case you need to place custom content define a pTemplate that gets the treenode as an implicit variable. Example below places an input field to create editable treenodes.

<ng-template let-node pTemplate="default">
<input [(ngModel)]="node.label" type="text" style="width:100%">
</ng-template>

Multiple templates are supported by matching the type property of the TreeNode with the type of pTemplate. If a node has no type, then default ng-template is used.

<ng-template let-node pTemplate="picture">

</ng-template>
<ng-template let-node pTemplate="default">
<input [(ngModel)]="node.label" type="text" style="width:100%">
</ng-template>

Tree has exclusive integration with context menu created by binding a menu instance to the tree.

Lazy loading is handy to deal with large datasets. Instead of loading the whole tree, nodes can be loaded at onNodeExpand event. Important part of implementing lazy loading is defining leaf property of a node as false, this will instruct tree to display an arrow icon to indicate there are children of this node although they are not loaded yet. When the lazy node is expanded, onNodeExpand is called and a remote call can be made to add the children to the expanded node.

export class TreeDemoComponent implements OnInit {
files: TreeNode[];
selectedFiles: TreeNode[];
constructor(private nodeService: NodeService) {}
ngOnInit() {
//initial nodes
this.nodeService.getFiles().then(files => this.files = files);
}
loadNode(event) {
if(event.node) {
//in a real application, make a call to a remote url to load children of the current node and add the new nodes as children
this.nodeService.getLazyFiles().then(nodes => event.node.children = nodes);
}
}
}
Assume at ngOnInit tree is initialized with a data like below that has nodes having no actual children but leaf property is set false.
{
"data":
[
{
"label": "Lazy Node 0",
"data": "Node 0",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"leaf": false
},
{
"label": "Lazy Node 1",
"data": "Node 1",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"leaf": false
},
{
"label": "Lazy Node 1",
"data": "Node 2",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"leaf": false
}
]
}
Nodes can be reordered within a tree and also can be transferred between multiple trees. To enable dragging from a tree set draggableNodes to true and to allow dropping enable droppableNodes property. In addition, import TreeDragDropService and configure it as a provider at your component or module.
import {TreeDragDropService} from 'primeng/primeng';

Multiple trees can be used in a drag drop operation, in order to add constraints like rejecting drags from a certain tree but allow from another use draggableScope and droppableScope properties which can be a string or an array. Following example uses 3 trees where second one only accepts drags from first tree and second one only accepts from second tree whereas first tree accepts drops from 3rd tree.

Tree has a loading property, when enabled a spinner icon is displayed to indicate data load.
An optional loadingIcon property can be passed in case you prefer a different icon.

Horizontal mode is the alternative option for orientation.

| Name | Type | Default | Description |
|---|---|---|---|
| value | array | null | An array of treenodes. |
| selectionMode | string | null | Defines the selection mode, valid values "single", "multiple", and "checkbox". |
| selection | any | null | A single treenode instance or an array to refer to the selections. |
| style | string | null | Inline style of the component. |
| styleClass | string | null | Style class of the component. |
| contextMenu | ContextMenu | null | Context menu instance. |
| layout | string | vertical | Defines the orientation of the tree, valid values are 'vertical' and 'horizontal'. |
| metaKeySelection | boolean | true | Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically. |
| propagateSelectionUp | boolean | true | Whether checkbox selections propagate to ancestor nodes. |
| propagateSelectionDown | boolean | true | Whether checkbox selections propagate to descendant nodes. |
| loading | boolean | false | Displays a loader to indicate data load is in progress. |
| loadingIcon | string | fa-circle-o-notch | The icon to show while indicating data load is in progress. |
| Name | Parameters | Description |
|---|---|---|
| onNodeSelect | event.originalEvent: browser event event.node: Selected node instance. |
Callback to invoke when a node is selected. |
| onNodeUnselect | event.originalEvent: browser event event.node: Unselected node instance. |
Callback to invoke when a node is unselected. |
| onNodeExpand | event.originalEvent: browser event event.node: Expanded node instance. |
Callback to invoke when a node is expanded. |
| onNodeCollapse | event.originalEvent: browser event event.node: Collapsed node instance. |
Callback to invoke when a node is collapsed. |
| onNodeContextMenuSelect | event.originalEvent: browser event event.node: Selected node instance. |
Callback to invoke when a node is selected with right click. |
| onNodeDrop | event.originalEvent: browser event event.dragNode: Dragged node instance event.dropNode: Dropped node instance. event.index: Index of the dropped node within siblings. |
Callback to invoke when a node is selected with right click. |
Following is the list of structural style classes, for theming classes visit theming page.
| Name | Element |
|---|---|
| ui-tree | Main container element |
| ui-tree-horizontal | Main container element in horizontal mode |
| ui-tree-container | Container of nodes |
| ui-treenode | A treenode element |
| ui-treenode-content | Content of a treenode |
| ui-treenode-toggler | Toggle icon |
| ui-treenode-icon | Icon of a treenode |
| ui-treenode-label | Label of a treenode |
| ui-treenode-children | Container element for node children |
| ui-treenode-content-selected | Content of a selected node. |
None.

Basic

Loader

Single Selection

Selected Node: {selectedFile ? selectedFile.label : 'none'}

Multiple Selection with Metakey

Selected Nodes: {file.label}

Multiple Selection with Checkbox

Selected Nodes: {file.label}

Lazy Loading

Template

<ng-template let-node pTemplate="default">
<input [(ngModel)]="node.label" type="text" style="width:100%">
</ng-template>

Context Menu

DragDrop

Files

Server 1

Server 2

Programatic Tree Expansion

<button pButton type="button" label="Expand all" (click)="expandAll()"></button>
<button pButton type="button" label="Collapse all" (click)="collapseAll()"></button>

Horizontal Tree

Selected Node: {selectedFile3 ? selectedFile3.label : 'none'}

export class TreeDemo implements OnInit {
msgs: Message[];
@ViewChild('expandingTree')
expandingTree: Tree;
filesTree1: TreeNode[];
filesTree2: TreeNode[];
filesTree3: TreeNode[];
filesTree4: TreeNode[];
filesTree5: TreeNode[];
filesTree6: TreeNode[];
filesTree7: TreeNode[];
filesTree8: TreeNode[];
filesTree9: TreeNode[];
filesTree10: TreeNode[];
filesTree11: TreeNode[];
lazyFiles: TreeNode[];
selectedFile: TreeNode;
selectedFile2: TreeNode;
selectedFile3: TreeNode;
selectedFiles: TreeNode[];
selectedFiles2: TreeNode[];
items: MenuItem[];
loading: boolean;
constructor(private nodeService: NodeService) { }
ngOnInit() {
this.loading = true;
this.nodeService.getFiles().then(files => this.filesTree0 = files);
setTimeout(() => {
this.nodeService.getFiles().then(files => this.filesTree1 = files);
this.loading = false;
}, 3000);
this.nodeService.getFiles().then(files => this.filesTree2 = files);
this.nodeService.getFiles().then(files => this.filesTree3 = files);
this.nodeService.getFiles().then(files => this.filesTree4 = files);
this.nodeService.getFiles().then(files => this.filesTree5 = files);
this.nodeService.getFiles().then(files => this.filesTree6 = files);
this.nodeService.getFiles().then(files => this.filesTree7 = files);
this.filesTree8 = [
{
label: "Backup",
data: "Backup Folder",
expandedIcon: "fa-folder-open",
collapsedIcon: "fa-folder"
}
];
this.filesTree9 = [
{
label: "Storage",
data: "Storage Folder",
expandedIcon: "fa-folder-open",
collapsedIcon: "fa-folder"
}
];
this.nodeService.getFiles().then(files => this.filesTree10 = files);
this.nodeService.getFiles().then(files => {
this.filesTree11 = [{
label: 'Root',
children: files
}];
});
this.nodeService.getLazyFiles().then(files => this.lazyFiles = files);
this.items = [
{label: 'View', icon: 'fa-search', command: (event) => this.viewFile(this.selectedFile2)},
{label: 'Unselect', icon: 'fa-close', command: (event) => this.unselectFile()}
];
}
nodeSelect(event) {
this.msgs = [];
this.msgs.push({severity: 'info', summary: 'Node Selected', detail: event.node.label});
}
nodeUnselect(event) {
this.msgs = [];
this.msgs.push({severity: 'info', summary: 'Node Unselected', detail: event.node.label});
}
nodeExpandMessage(event) {
this.msgs = [];
this.msgs.push({severity: 'info', summary: 'Node Expanded', detail: event.node.label});
}
nodeExpand(event) {
if(event.node) {
//in a real application, make a call to a remote url to load children of the current node and add the new nodes as children
this.nodeService.getLazyFiles().then(nodes => event.node.children = nodes);
}
}
viewFile(file: TreeNode) {
this.msgs = [];
this.msgs.push({severity: 'info', summary: 'Node Selected with Right Click', detail: file.label});
}
unselectFile() {
this.selectedFile2 = null;
}
expandAll(){
this.filesTree6.forEach( node => {
this.expandRecursive(node, true);
} );
}
collapseAll(){
this.filesTree6.forEach( node => {
this.expandRecursive(node, false);
} );
}
private expandRecursive(node:TreeNode, isExpand:boolean){
node.expanded = isExpand;
if(node.children){
node.children.forEach( childNode => {
this.expandRecursive(childNode, isExpand);
} );
}
}
}


| Item Name | Qty. |
|---|---|
| Wall to Glass Hinge | 4 |
| Glass to Glass Hinge 180 | 2 |
| Floor to Glass Bracket | 2 |
| Water Disperser L=2000mm | 1 |
| Middle Seal 1-2500 Long. | 1 |
| Magnetic Seal -2500mm | 1 |
| Towel Rod Cum Handrail | 1 |
| Support Bar -19mm Dia Rod | 1 |
| Wall to Rod Connector | 2 |
| Rod to Glass Clamp | 2 |


We tried our best to give you best experience. Every detail and
every small touch designed for best comfort.
+ Limited edition case
+ Limited edition cable
+ Lifetime support
Only for you!


Creating your uniqie TEC Redshift™ is just a few clicks away.
Simply use the buttons below to upload
If you are looking for unique and itneresting cartridge colors, take a look at our cartridge catalog.
Step 1: Upload your original PNG TEC Redshift Cartridge:
Step 2: Upload your new PNG TEC Redshift Cartridge:
DATA
is output to the left.DATA
line(s) are file offsets for each frame index. Each frame is terminated by a 0
.SEEK
ing to the frame offset, the copying F
to GP
until F = 0
.


Enumerable Methods: Enumerable#map
January 29, 2016
According to ruby-docs.org,
Returns a new array with the results of running block once for every element in enum. If no block is given, an enumerator is returned instead.
But what does this mean?
#map is going to create and return a new array or hash. It will also execute the code inside the block once for every element in the array or hash. It will take the results for executing the code, and put it into the new array. This code may modify elements from the original array/hash, or not.
Here are the examples from ruby-docs.org
(1..4).map { |i| i*i } #=> [1, 4, 9, 16]
(1..4).collect { "cat" } #=> ["cat", "cat", "cat", "cat"]
In the first example, #map is iterating over the array, accessing the element of the current iteration, squaring it, and putting it into the returned array.
In the second example, #collect (an alias for #map), is iterating over the array, executing the block of code (which is just the string "cat"), and inserting the result into the returned array.
The same will happen if the method were called on a hash.
{a:1, b:2}.map { "cat" } #=> ["cat", "cat"]
To demonstrate that this methods returns a new array...
a = (1..4)
a.map { |i| i*i } == a #=> false


A frequent job in data visualizing is to present summary statistics. In this post, I show one way to plot mean values between groups using the tidyverse approach in comparison to the mosaic way.
library(tidyverse)
data(mtcars)
library(mosaic)
library(knitr)
library(sjmisc)
library(sjPlot)
Visualizing mean values between two groups
First, let’s compute the mean hp for automatic cars (am == 0
) vs. manual cars (am == 1
).
mtcars %>%
group_by(am) %>%
summarise(hp_am = mean(hp)) -> hp_am
Now just hand over this data frame of summarized data to ggplot:
hp_am %>%
ggplot() +
aes(x = factor(am), y = hp_am) +
geom_point(aes(shape = factor(am)), size = 5, alpha = .7) +
geom_line(group = 1) -> p1
p1
An alternative approach would be using the R package mosaic
:
favstats(hp ~ am, data = mtcars) %>%
rownames_to_column() -> mtcars_favstats
Now hand over this data frame to gf_XXX()
from mosaic
(wrappers around ggplot()
):
gf_point(mean ~ rowname, data = mtcars_favstats, shape = ~rowname, size = 5, alpha = .7) %>%
gf_line(mean ~ rowname, group = 1)
Adding uncertainty measures
If we are not primarily interested in sample description but population estimation we need to add uncertainty measures - such as the standard error (SE).
One easy solution is to make use of the package gplots
:
library(gplots)
plotmeans(hp ~ am, data = mtcars)
Note that the errors describe the 95% confidence interval of the respective mean.
Using ggplot2, there are some helper functions from hmisc
that will do to computation of the standard error for us. One way is to use the stat_summary()
function:
p1 +
stat_summary(fun.data = "mean_cl_normal", geom = "errorbar", data = mtcars, aes(y = hp))
stat_summary()
provides an alternative to geom_XXX()
for building a plot. Here the focus lies on “which summary statistic do I want to compute?
mean_cl_normal
computes the mean and the confidence limits based on a t-distribution. As an alternative mean_cl_boot
would produce a less assumption laden bootstrapped confidence interval.
geom_errorbar()
yields essentially the same result. Here, we also specify that we do not want the 2-SE-interval (95%) but the 1-SE-interval (via fun.args
).
p1 +
geom_errorbar(stat = "summary", fun.data = "mean_sdl",
fun.args = list(mult = 1),
position = position_dodge(width = 0.9),
data = mtcars,
aes(y = hp))
stat = "summary"
computes a summary at each position of x. In this case, the summary function mean_sdl
is called. fun_data
returns three values: y
, ymin
and ymax
.
Less intrusive bars
I personally find the bars to intrusive; let’s try to deemphasize their appearance.
mtcars %>%
ggplot() +
aes(x = factor(am), y = hp) +
geom_pointrange(stat = "summary", fun.data = "mean_sdl",
fun.args = list(mult = 1),
position = position_dodge(width = 0.9),
size = 2,
aes(y = hp, shape = factor(am), color = factor(am))) +
geom_line(stat = "summary", fun.data = "mean_sdl",
group = 1)
Plot table
Sometimes, we do not (only) want a diagram but also the exact figures. How to get that? kable()
provides a convenient way:
hp_am %>%
kable()
| am | hp_am |
|---|---|
| 0 | 160.2632 |
| 1 | 126.8462 |
The package sjmisc
provides a convenience function for summary statistics:
mtcars %>%
group_by(am) %>%
select(hp) %>%
descr()
#>
#> ## Basic descriptive statistics
#>
#> Grouped by:
#> am: 0
#> var type label n NA.prc mean sd se md trimmed range
#> hp numeric hp 19 0 160.26 53.91 12.37 175 161.06 183 (62-245)
#> skew
#> -0.02
#>
#> Grouped by:
#> am: 1
#> var type label n NA.prc mean sd se md trimmed range
#> hp numeric hp 13 0 126.85 84.06 23.31 109 114.73 283 (52-335)
#> skew
#> 1.74
Double grouping
Let’s try a double grouping and see where it takes us:
mtcars %>%
group_by(am, cyl) %>%
summarise(hp_mean = mean(hp)) %>%
ungroup() -> hp_am_cyl
hp_am_cyl
#> # A tibble: 6 x 3
#> am cyl hp_mean
#> <dbl> <dbl> <dbl>
#> 1 0 4 84.7
#> 2 0 6 115.
#> 3 0 8 194.
#> 4 1 4 81.9
#> 5 1 6 132.
#> 6 1 8 300.
Now let’s add the mean per am
group (the “overall” means):
hp_am_cyl %>%
group_by(am) %>%
mutate(overall_mean = mean(hp_mean)) -> hp_am_cyl
hp_am_cyl %>% kable()
| am | cyl | hp_mean | overall_mean |
|---|---|---|---|
| 0 | 4 | 84.66667 | 131.3611 |
| 0 | 6 | 115.25000 | 131.3611 |
| 0 | 8 | 194.16667 | 131.3611 |
| 1 | 4 | 81.87500 | 171.0139 |
| 1 | 6 | 131.66667 | 171.0139 |
| 1 | 8 | 299.50000 | 171.0139 |
This format is called the long format. We can shift it to the wide format:
hp_am_cyl %>%
spread(key = cyl, value = hp_mean) %>%
kable()
| am | overall_mean | 4 | 6 | 8 |
|---|---|---|---|---|
| 0 | 131.3611 | 84.66667 | 115.2500 | 194.1667 |
| 1 | 171.0139 | 81.87500 | 131.6667 | 299.5000 |
Plot multiple grouping
hp_am_cyl %>%
ggplot(aes(x = factor(am), color = factor(cyl), y = hp_mean)) +
geom_point(aes(shape = factor(am))) +
geom_line(aes(group = factor(cyl)))


Today's weather details
Precipitation
Max Temperature:
Min Temperature:
Pressure
Wind Speed
Wind direction


WITNESS LIST Insurance Committee (SUBCOMMITTEE ON Subcommittee on Life and Health Insurance) April 21, 2005-12:00A HB 1784 For: Barker, Conni (De Pelchin Children's Center) Beeson, Jan (Self) C. Hersendoeder, Albert (Texas Children's Hospital and Baylor College of Medicine) Chou, Kelley (Self) Gamblian, Vivian (Self) Gantt, Melanie (Mental Health Association in Texas) Gerber, Leslie (Mental Health Assn. of Houston) Hopkins, Cynthia (Self) Kern, Diana (Nami Texas- National Alliance for the Mentally Ill) Montaner, Dawn (Lifelines Foundation for Eating Disorders) Rachofsky, Marcia C. (Texas Mental Health Consumers) Santos, George (Federation of Texas Psychiatry) Against: Green, Shelton (Texas Association of Business) HB 1785 For: C. Hersendoeder, Albert (Texas Children's Hospital and Baylor College of Medicine) Gantt, Melanie (Mental Health Association in Texas) Hopkins, Cynthia (Self) Kern, Diana (Nami Texas- National Alliance for the Mentally Ill) Rachofsky, Marcia C. (Texas Mental Health Consumers) Santos, George (Federation of Texas Psychiatry) Against: Green, Shelton (Texas Association of Business) HB 1786 For: Barker, Conni (De Pelchin Children's Center) Beeson, Jan (Self) C. Hersendoeder, Albert (Texas Children's Hospital and Baylor College of Medicine) Gamblian, Vivian (Self) Gantt, Melanie (Mental Health Association in Texas) Goff, Kerrie (Self and ANAD) Hopkins, Cynthia (Self) Kern, Diana (Nami Texas- National Alliance for the Mentally Ill) Montaner, Dawn (Lifelines Foundation for Eating Disorder) Rachofsky, Marcia C. (Texas Mental Health Consumers) Santos, George (Federation of Texas Psychiatry) Wyman, Dwaine (Self) Against: Green, Shelton (Texas Association of Business) HB 1947 For: Kolodzey, Patricia (Texas Hospital Association) Against: Green, Shelton (Texas Association of Business) Pollard, Milke (TALHI) HB 1948 Against: Green, Shelton (Texas Association of Business) HB 2493 For: Hawkins, Clare (Texas Academy of Family Physicians) HB 2813 Against: Pollard, Mike (TALHI) HB 3411 For: Barker, Conni (De Pelchin Children's Center) Gamblian, Vivian (Self) Gantt, Melanie (Mental Health Association in Texas) Kern, Diana (Nami Texas- National Alliance for the Mentally Ill) Santos, George (Federation of Texas Psychiatry)


VisCompClass
allows visible objects to have children. VisComp objects are the grouping elements within visible object trees.
If you need to have a visible object tree with several levels, or if you need to manage the geometry of visible objects, you will want to read this chapter. You should already be familiar with
VisClass
1 VisCompClass Features
2 VisCompClass Instance Data
2.1 VCI_comp
2.2 VCI_gadgetExcl
2.3 VCI_window
2.4 VCI_geoAttrs
2.5 VCI_geoDimensionAttrs
2.6 Managing Instance Data
3 Using VisCompClass
3.1 Managing Geometry
3.2 Managing Graphic Windows