Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Artist #6

Merged
merged 8 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rubyonrails.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
with:
bundler-cache: true
- name: Generate binstubs
run: bundle binstubs bundler-audit brakeman rubocop
run: bundle binstubs bundler-audit brakeman
# Add or replace any other lints here
- name: Security audit dependencies
run: bin/bundler-audit --update
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@

# Ignore master key for decrypting credentials and more.
/config/master.key

coverage
45 changes: 45 additions & 0 deletions app/controllers/api/v1/artists_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class Api::V1::ArtistsController < ApplicationController
def index
if params[:name]
begin
artists = ArtistFacade.search_artists(params[:name])
render json: ArtistSerializer.new(artists)
rescue JSON::ParserError => e
render json: { errors: [{ detail: "Failed to parse response: #{e.message}" }] }, status: :internal_server_error
rescue StandardError => e
render json: ErrorSerializer.new(e).serialize_json, status: :internal_server_error
end
else
error = ErrorSerializer.new(StandardError.new('Name parameter is required'))
render json: error.serialize_json, status: :bad_request
end
end

def create
user = User.find(params[:user_id])
artist = Artist.find_or_create_by!(artist_params)

UserArtist.find_or_create_by!(user: user, artist: artist)

render json: artist, status: :ok
rescue ActiveRecord::RecordNotFound => e
render json: ErrorSerializer.new(e).serialize_json, status: :not_found
rescue ActiveRecord::RecordInvalid => e
render json: ErrorSerializer.new(e).serialize_json, status: :bad_request
end

def destroy
user_artist = UserArtist.find_by!(user_id: params[:user_id], artist_id: params[:id])
user_artist.destroy

render json: { message: "Artist removed from user's saved artists" }, status: :ok
rescue ActiveRecord::RecordNotFound => e
render json: ErrorSerializer.new(e).serialize_json, status: :not_found
end

private

def artist_params
params.require(:artist).permit(:name, :musicbrainz_id)
end
end
12 changes: 12 additions & 0 deletions app/facades/artist_facade.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class ArtistFacade
def self.search_artists(name)
artists_data = ArtistService.get_artists_by_name(name)
artists_data.map do |artist_data|
condensed_data = {
name: artist_data[:name],
id: artist_data[:id]
}
Artist.new(condensed_data)
end
end
end
7 changes: 7 additions & 0 deletions app/models/artist.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Artist < ApplicationRecord
has_many :user_artists
has_many :users, through: :user_artists

validates :name, presence: true
validates :musicbrainz_id, presence: true, uniqueness: true
end
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class User < ApplicationRecord
has_many :user_events
has_many :events, through: :user_events
has_many :user_artists, through: :user_artists
has_many :artists, through: :user_artists

validates :name, presence: true
validates :email, presence: true
Expand Down
7 changes: 7 additions & 0 deletions app/models/user_artist.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class UserArtist < ApplicationRecord
belongs_to :user
belongs_to :artist

validates :user_id, presence: true
validates :artist_id, presence: true
end
8 changes: 8 additions & 0 deletions app/poros/artist.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Artist
attr_reader :name, :musicbrainz_id

def initialize(data)
@name = data[:name]
@musicbrainz_id = data[:id]
end
end
4 changes: 4 additions & 0 deletions app/serializers/artist_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class ArtistSerializer
include JSONAPI::Serializer
attributes :name, :musicbrainz_id
end
13 changes: 13 additions & 0 deletions app/services/artist_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class ArtistService
def self.get_conn
Faraday.new(url: 'https://musicbrainz.org/ws/2') do |faraday|
faraday.headers['Content-Type'] = 'application/json'
faraday.adapter Faraday.default_adapter
end
end

def self.get_artists_by_name(name)
response = get_conn.get('/artist', { query: "artist:#{name}", fmt: 'json' })
JSON.parse(response.body, symbolize_names: true)[:artists]
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
resources :events, only: [:show, :create, :update, :destroy]
resources :users, only: [:show, :create, :update, :destroy]
resources :user_events, only: [:show, :create, :update, :destroy]
resources :artists, only: [:index, :create, :destroy]
end
end
end
5 changes: 0 additions & 5 deletions coverage/.last_run.json

This file was deleted.

Loading