Airbnb is a single-page, full stack web application (SPA) inspired by Airbnb where users can view, book, and search for listings by location.
It utilizes Ruby on Rails with a PostgreSQL database on the back-end, and React.js and Redux on the front-end.
User credentials are securely hashed, salted, and stored as a password digest
class User < ApplicationRecord
validates :username, :session_token, uniqueness: true
validates :username, presence: true
validates :password, length: {minimum: 6, allow_nil: true}
// ..
attr_reader :password
before_validation :ensure_session_token
def self.find_by_credentials(username, password)
@user = User.find_by(username: username)
return nil unless @user
@user.is_password?(password) ? @user : nil
end
def password=(password)
@password = password
self.password_digest = BCrypt::Password.create(password)
end
def is_password?(password)
BCrypt::Password.new(self.password_digest).is_password?(password)
end
def ensure_session_token
self.session_token ||= SecureRandom::urlsafe_base64
end
def reset_session_token!
self.session_token = SecureRandom::urlsafe_base64
end
end
As a user moves the map around, the new bounds (coordinates) will get updated in realtime and send the correct listings from the backend (PostgreSQL database)
class Listing < ApplicationRecord
// ..
def self.in_bounds(bounds)
bounds = JSON.parse(bounds)
self.where('lat < ?', bounds["northEast"]["lat"].to_f)
.where('lat >?', bounds["southWest"]["lat"].to_f)
.where('long < ?', bounds["northEast"]["lng"].to_f)
.where('long > ?', bounds["southWest"]["lng"].to_f)
end
// ..
end
The Google Maps API is integrated into the appropriate React frontend components
class ListingMap extends React.Component {
constructor(props) {
super(props);
this.renderMap = this.renderMap.bind(this);
this.handleMarkerClick = this.handleMarkerClick.bind(this);
}
// ..
renderMap() {
const mapOptions = {
center: this.props.mapSearchCoords,
zoom: 13,
gestureHandling: "greedy"
};
this.map = new google.maps.Map(this.mapNode, mapOptions);
this.MarkerManager = new MarkerManager(this.map, this.handleMarkerClick);
this.registerListeners();
this.MarkerManager.updateMarkers(this.props.listings);
}
registerListeners() {
google.maps.event.addListener(this.map, 'idle', () => {
const { north, south, east, west } = this.map.getBounds().toJSON();
let bounds = {
northEast: { lat: north, lng: east },
southWest: { lat: south, lng: west }
};
this.props.updateFilter("bounds", bounds);
});
// ..
}
Aerbnb is a single-page web application with one backend route responsible for rendering HTML. User interactions in the front-end side trigger AJAX requests to the back-end, which is responsible for rendering database information in JSON format.
The Rails backend API is connected to a React frontend to efficiently render to the virtual DOM.
Redux manages the front-end state of Aerbnb. When database information is retrieved, Redux state is updated first and re-renders the appropriate React components.
Ruby on Rails is the back-end framework used to query the database.
Airbnb uses a PostgreSQL database to store its relational data.