Skip to content

feat: make it works for rails 8 #15

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

Merged
merged 2 commits into from
Mar 16, 2025
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
30 changes: 30 additions & 0 deletions .github/workflows/release_please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
on:
push:
branches:
- main

permissions:
contents: write
pull-requests: write
id-token: write

name: release-please

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
config-file: .release-please-config.json
- uses: actions/checkout@v4
if: ${{ steps.release.outputs.release_created }}
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
if: ${{ steps.release.outputs.release_created }}
- uses: rubygems/release-gem@v1
if: ${{ steps.release.outputs.release_created }}
49 changes: 49 additions & 0 deletions .github/workflows/rubyonrails.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# This workflow uses actions that are not certified by GitHub. They are
# provided by a third-party and are governed by separate terms of service,
# privacy policy, and support documentation.
#
# This workflow will install a prebuilt Ruby version, install dependencies, and
# run tests and linters.
name: "Ruby on Rails CI"
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
test:
strategy:
fail-fast: false
matrix:
gemfile: [rails-7.0, rails-7.1, rails-7.2, rails-8.0]
runs-on: ubuntu-latest
env:
RAILS_ENV: test
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Ruby and gems
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Run tests
run: bin/rails t

lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Ruby and gems
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install Security Scan Gems
run: gem install bundler-audit brakeman rubocop
- name: Security audit dependencies
run: bundler-audit --update
- name: Security audit application code
run: brakeman -q -w2
- name: Lint Ruby files
run: bundle exec rubocop --parallel
7 changes: 3 additions & 4 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
require: rubocop-rails


AllCops:
TargetRubyVersion: 2.7
TargetRubyVersion:
NewCops: enable
Exclude:
- 'db/**/*'
- 'config/**/*'
- 'bin/{rails,rake}'
- 'test/**/*'
- "gemfiles/*"
- "vendor/**/*"

Style/FrozenStringLiteralComment:
Enabled: false
Expand Down
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.4.2
13 changes: 6 additions & 7 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Specify your gem's dependencies in rails_url_shortener.gemspec.
gemspec

gem 'rails', '>= 7.0.2.3'
gem 'rails', '~> 7.2'

gem 'sqlite3'

gem 'sprockets-rails'
Expand All @@ -21,10 +22,8 @@ group :test do
gem 'vcr'
end

gem 'rubocop', require: false
gem 'rubocop-minitest', require: false
gem 'rubocop-rails', require: false

gem 'minitest-cc'
group :development, :test do
gem 'rubocop'

gem 'annotate'
gem 'minitest-cc'
end
27 changes: 5 additions & 22 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ PATH
specs:
rails_url_shortener (0.2.10)
browser (>= 5.3.0)
bundler (>= 1.15.0)
http (>= 5.1.0)

GEM
Expand Down Expand Up @@ -82,9 +81,6 @@ GEM
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0)
ast (2.4.2)
base64 (0.2.0)
benchmark (0.4.0)
Expand Down Expand Up @@ -144,7 +140,7 @@ GEM
net-smtp
marcel (1.0.4)
mini_mime (1.1.5)
minitest (5.25.4)
minitest (5.25.5)
minitest-cc (1.0.0)
net-imap (0.5.6)
date
Expand All @@ -156,7 +152,7 @@ GEM
net-smtp (0.5.1)
net-protocol
nio4r (2.7.4)
nokogiri (1.18.3-x86_64-linux-gnu)
nokogiri (1.18.4-x86_64-linux-gnu)
racc (~> 1.4)
parallel (1.26.3)
parser (3.3.7.1)
Expand Down Expand Up @@ -215,7 +211,7 @@ GEM
reline (0.6.0)
io-console (~> 0.5)
rexml (3.4.1)
rubocop (1.73.2)
rubocop (1.74.0)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
Expand All @@ -226,18 +222,8 @@ GEM
rubocop-ast (>= 1.38.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.38.1)
rubocop-ast (1.39.0)
parser (>= 3.3.1.0)
rubocop-minitest (0.37.1)
lint_roller (~> 1.1)
rubocop (>= 1.72.1, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
rubocop-rails (2.30.3)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
rubocop (>= 1.72.1, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
ruby-progressbar (1.13.0)
securerandom (0.4.1)
sprockets (4.2.1)
Expand Down Expand Up @@ -273,15 +259,12 @@ PLATFORMS
x86_64-linux

DEPENDENCIES
annotate
byebug
faker
minitest-cc
rails (>= 7.0.2.3)
rails (~> 7.2)
rails_url_shortener!
rubocop
rubocop-minitest
rubocop-rails
sprockets-rails
sqlite3
vcr
Expand Down
83 changes: 39 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,53 @@
# RailsUrlShortener

RailsUrlShortener is a small rails engine that provide your app with short URLs functionalities. Like a Bitly on your app. By default, RailsUrlShortener save the visits to your link for future interesting things that you may want to do.
RailsUrlShortener is a small Rails engine that provides your app with short URL functionality and IP logging capabilities - like having your own Bitly service. By default, RailsUrlShortener saves all visits to your links for future analysis or other interesting uses.

Why give your data to a third party app if you can do it by yourself?
Why give your data to a third-party app when you can manage it yourself?

You can see a **demo project** of what you can do with this engine [HERE](https://paso.fly.dev/).

## Key features
## Key Features

A few of the things you can do with RailsUrlShortener:
Here are some of the things you can do with RailsUrlShortener:

* Generate unique keys for links.
* Provide a method controller that find, save request information and does a 301 redirect to the original url.
* The short links can be associated with a model in your app.
* Save interesting things like browser, system and ip data of the 'un-shortened' request.
* Temporal short links using the expires_at option.
* Get IP data from third part service.
* Generate unique keys for links
* Provide a controller method that finds, saves request information, and performs a 301 redirect to the original URL
* Associate short links with models in your app
* Save browser, system, and IP data from each request
* Create temporary short links using the expires_at option
* Get IP data from a third-party service

## Installation

Add this line to your application's Gemfile:
Follow these steps to install and configure RailsUrlShortener:

1. Add this line to your application's Gemfile:

```ruby
gem "rails_url_shortener"
```

Or install it yourself as:

```bash
gem install rails_url_shortener
```

Then execute:
2. Install the gem by running:

```bash
bundle
bundle install
```

And finally install & run the migrations on your project and migrate:
3. Install and run the migrations:

```bash
bin/rails rails_url_shortener:install:migrations db:migrate
```

For the configurations generate the initializer whith this:
4. Generate the initializer for configuration:

```bash
rails generate RailsUrlShortener:initializer
rails generate rails_url_shortener
```

**Here is important to configure the host at least if your are not running your app in localhost**

## Usage

### 1. Mount the engine
1. Mount the engine

Mount the engine on your app adding the next code on your config/routes.rb:

Expand All @@ -64,7 +58,7 @@ mount RailsUrlShortener::Engine, at: "/"

```

### 2. Generate the short link
2. Generate the short link

And generate the short links like you want:

Expand All @@ -80,7 +74,7 @@ short_url("https://www.github.com/a-chacon/rails-url-shortener")
RailsUrlShortener::Url.generate("https://www.github.com/a-chacon/rails-url-shortener")
```

### 3. Share the short link
3. Share the short link

**Then share the short link to your users or wherever you want.**

Expand All @@ -94,43 +88,44 @@ short_url(url, owner: nil, key: nil, expires_at: nil, category: nil, url_options

Where:

* **url**: Long url for short.
* **owner**: Is a model of your app. You can relate an url whatever you want in your app.
* **key**: Is a custom key that you want to set up.
* **expires_at**: Is a datetime for expiration, after this the redirection doesn't work.
* **category**: Tag that you want for that link.
* **url_options**: Options for the url_for generator. Ex: subdomain or protocol.
* **url**: The long URL to be shortened
* **owner**: A model from your app to associate with the URL
* **key**: A custom key for the short URL (optional)
* **expires_at**: Expiration datetime (after which the redirect won't work)
* **category**: A tag for categorizing the link
* **url_options**: Options for the URL generator (e.g., subdomain or protocol)

And the same for the generate model method except for url_options:
The `generate` model method accepts the same parameters except for `url_options`:

```ruby
RailsUrlShortener::Url.generate(url, owner: nil, key: nil, expires_at: nil, category: nil)
```

### Data saved
### Data Collection

By default, this engine save all request made on your short url, you can use that data for some analytics or simple IP logger. So for get the data in a controller or do wherever you want, you can use the Visit model related to an Url:
By default, the engine saves all requests made to your short URLs. You can use this data for analytics or IP logging. To access the data:

```ruby
RailsUrlShortener::Url.find_by_key("key").visits # all visits
1. Get visits for a specific URL:

```ruby
RailsUrlShortener::Url.find_by_key("key").visits
```

Or using the model class:
2. Get all visits:

```ruby
RailsUrlShortener::Visit.all # all in database
RailsUrlShortener::Visit.all
```

And a Visit is related to a Ipgeo model that contain information about the ip, so you can view this using the active record relation:
Each Visit is associated with an Ipgeo model that contains information about the IP address:

```ruby
RailsUrlShortener::Visit.first.ipgeo # Ipgeo object that contain information of the ip
RailsUrlShortener::Visit.first.ipgeo
```

### Ip data
### IP Data Collection

When a Visit record is created, a job is enqueue for get Ip data from [this](https://ip-api.com/) service and create the Ipgeo record. It is integrated to the free endpoint, so if you think that you have more than 45 different IPS querying in a minute to your app, we need to think in a new solution.
When a Visit record is created, a background job is enqueued to fetch IP data from the [ip-api.com](https://ip-api.com/) service and create an Ipgeo record. This uses the free endpoint, which has a limit of 45 different IPs per minute. If you expect higher traffic, you'll need to implement an alternative solution.

## Contributing

Expand Down
8 changes: 1 addition & 7 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,4 @@ Rake::TestTask.new(:test) do |t|
t.test_files = FileList['test/**/*test.rb']
end

require 'rubocop/rake_task'

RuboCop::RakeTask.new do |task|
task.requires << 'rubocop-minitest'
end

task default: %i[test rubocop]
task default: %i[test]
Loading