Skip to content

Commit

Permalink
Merge pull request #42 from turingschool/jm/create_tags
Browse files Browse the repository at this point in the history
Feat: user can create new tags
  • Loading branch information
noahdurbin authored Sep 17, 2024
2 parents 8ba5624 + 689308c commit 111d12a
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 7 deletions.
29 changes: 26 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ This is the backend API repository for TurLink. TurLink is a link shortener app
```

### Add a tag to a link
- **POST** `/api/v1/tags?link={link_id}&tag={tag_id}`
- Description: Adds a tag to a link
- Example Request: POST `https://turlink-be-53ba7254a7c1.herokuapp.com/api/v1/tags?link=1&tag=1`
- **POST** `/api/v1/tags?link={link_id}&tag={tag_id}` OR `/api/v1/tags?link={link_id}&newTag={user created tag}`
- Description: Adds a tag to a link, or creates a new tag and adds it to a link
- Example Request for adding an existing tag: POST `https://turlink-be-53ba7254a7c1.herokuapp.com/api/v1/tags?link=1&tag=1`
- Successful Response (200 OK):
```json
{
Expand All @@ -307,6 +307,29 @@ This is the backend API repository for TurLink. TurLink is a link shortener app
}
}
```
- Example Request for creating and adding a new tag: POST `https://turlink-be-53ba7254a7c1.herokuapp.com/api/v1/tags?link=1&newTag=miscellaneous`
- Successful Response (200 OK):
```json
{
"data": {
"id": "1",
"type": "link",
"attributes": {
"original": "testlink.com",
"short": "tur.link/4a7c204baeacaf2c",
"user_id": 1,
"tags": [
{
"id": 173,
"name": "miscellaneous",
"created_at": "2024-08-27T01:19:47.421Z",
"updated_at": "2024-08-27T01:19:47.421Z"
}
]
}
}
}
```
- Error Response (404 Not Found) -- when tag or link doesn't exist or isn't passed as a param:
```json
{
Expand Down
19 changes: 15 additions & 4 deletions app/controllers/api/v1/tags_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ def index

def create
link = Link.find(params[:link])
tag = Tag.find(params[:tag])
link_tag = LinkTag.new(link_id: link.id, tag_id: tag.id)
if link_tag.save
render json: LinkSerializer.new(link)
if params[:tag].present?
tag = Tag.find(params[:tag])
create_link_tag(link, tag)
elsif params[:newTag].present?
tag = Tag.create_new(params[:newTag])
create_link_tag(link, tag)
else
not_found_error
end
end

Expand All @@ -34,4 +38,11 @@ def destroy
def not_found_error
render json: { errors: [{ message: 'Link or Tag not found' }] }, status: :not_found
end

def create_link_tag(link, tag)
link_tag = LinkTag.new(link_id: link.id, tag_id: tag.id)
if link_tag.save
render json: LinkSerializer.new(link)
end
end
end
9 changes: 9 additions & 0 deletions app/models/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,13 @@ class Tag < ApplicationRecord

has_many :link_tags
has_many :links, through: :link_tags

def self.create_new(new_tag)
tag = where("name ILIKE ?", new_tag.strip)
if tag != []
return tag[0]
else
return Tag.create(name: new_tag.strip)
end
end
end
17 changes: 17 additions & 0 deletions spec/models/tag_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,21 @@
it { should have_many(:links).through(:link_tags) }
end

describe 'class methods' do
describe '#create_new' do
it 'can search database for existing tags - case insensitive, and return the tag' do
tag = Tag.create(name: "rails")
new_tag = Tag.create_new("Rails")
expect(tag).to eq(new_tag)
end

it "will create a new tag if tag does not yet exist" do
new_tag = Tag.create_new("new topic")
expect(Tag.last).to eq(new_tag)
expect(new_tag).to be_a Tag
expect(new_tag.name).to eq("new topic")
end
end
end

end
28 changes: 28 additions & 0 deletions spec/requests/api/v1/tags_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,34 @@
expect(first_tag[:name]).to eq("javascript")
end

it 'can create a new tag and add it to a link' do
user1 = User.create(email: "[email protected]", password: "user123")
post "/api/v1/users/#{user1.id}/links?link=long-link-example.com"

post "/api/v1/tags?link=#{Link.last.id}&newTag=new tech topic"

expect(response).to be_successful
expect(response.status).to eq(200)

link = JSON.parse(response.body, symbolize_names: true)[:data]

expect(link).to be_a Hash
expect(link).to have_key :id
expect(link[:type]).to eq("link")

attrs = link[:attributes]
expect(attrs[:original]).to eq("long-link-example.com")
expect(attrs[:short]).to be_a String
expect(attrs[:user_id]).to eq(user1.id)

tags = attrs[:tags]
expect(tags).to be_a Array
first_tag = tags[0]
expect(first_tag).to be_a Hash
expect(first_tag).to have_key :id
expect(first_tag[:name]).to eq("new tech topic")
end

describe "sad path" do
it "returns 404 when link or tag isn't passed or doesn't exist" do
user1 = User.create(email: "[email protected]", password: "user123")
Expand Down

0 comments on commit 111d12a

Please sign in to comment.