Skip to content

Commit

Permalink
Add Mongoid example
Browse files Browse the repository at this point in the history
  • Loading branch information
vipulnsward committed Oct 22, 2024
1 parent 814bb21 commit 0f8d7fd
Show file tree
Hide file tree
Showing 22 changed files with 583 additions and 7 deletions.
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,9 @@ gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby]
# Uploadcare-rails provides unified API interface to Uploadcare API
gem "uploadcare-rails", git: "https://github.com/uploadcare/uploadcare-rails.git", branch: "main"
gem "uploadcare-ruby", git: "https://github.com/uploadcare/uploadcare-ruby.git", branch: "main"

# Use MongoDB for the database, with Mongoid as the ODM
gem "mongoid", "9.0.1"

# The Rails CLI tool for MongoDB
gem "railsmdb", "1.0.0.alpha3"
29 changes: 28 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GIT
remote: https://github.com/uploadcare/uploadcare-rails.git
revision: eb273134e95d9bfafc8953b63db41639b934bbf1
revision: cbf92458e21539b3fcbd8b3b09fc68d27a72c221
branch: main
specs:
uploadcare-rails (3.4.3)
Expand Down Expand Up @@ -105,6 +105,7 @@ GEM
msgpack (~> 1.2)
brakeman (6.1.2)
racc
bson (5.0.1)
builder (3.2.4)
byebug (11.1.3)
capybara (3.40.0)
Expand Down Expand Up @@ -147,6 +148,11 @@ GEM
factory_bot_rails (6.4.3)
factory_bot (~> 6.4)
railties (>= 5.0.0)
faraday (2.11.0)
faraday-net_http (>= 2.0, < 3.4)
logger
faraday-net_http (3.3.0)
net-http
ffi (1.17.0-aarch64-linux-gnu)
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86_64-darwin)
Expand Down Expand Up @@ -184,6 +190,7 @@ GEM
llhttp-ffi (0.5.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
logger (1.6.1)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
Expand All @@ -198,9 +205,18 @@ GEM
nokogiri (~> 1)
rake
mini_mime (1.1.5)
minitar (0.12.1)
minitest (5.23.1)
mongo (2.20.1)
bson (>= 4.14.1, < 6.0.0)
mongoid (9.0.1)
activemodel (>= 5.1, < 7.2, != 7.0.0)
concurrent-ruby (>= 1.0.5, < 2.0)
mongo (>= 2.18.0, < 3.0.0)
msgpack (1.7.2)
mutex_m (0.2.0)
net-http (0.4.1)
uri
net-imap (0.4.11)
date
net-protocol
Expand All @@ -219,6 +235,7 @@ GEM
racc (~> 1.4)
nokogiri (1.16.5-x86_64-linux)
racc (~> 1.4)
os (1.1.4)
parallel (1.24.0)
parser (3.3.1.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -276,6 +293,13 @@ GEM
json
require_all (~> 3.0)
ruby-progressbar
railsmdb (1.0.0.alpha3)
faraday (~> 2.7)
minitar (~> 0.9)
mongoid (>= 8.0)
os (~> 1.1)
rails (~> 7.0)
rubyzip (~> 2.3)
railties (7.1.3.3)
actionpack (= 7.1.3.3)
activesupport (= 7.1.3.3)
Expand Down Expand Up @@ -370,6 +394,7 @@ GEM
dry-monads (~> 1.6)
hashie (~> 5.0)
http (~> 5.1)
uri (0.13.1)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand Down Expand Up @@ -404,12 +429,14 @@ DEPENDENCIES
factory_bot_rails
importmap-rails
jbuilder
mongoid (= 9.0.1)
pg (~> 1.5, >= 1.5.6)
propshaft
puma (>= 5.0)
rails (~> 7.1)
rails-controller-testing
rails_best_practices
railsmdb (= 1.0.0.alpha3)
redis (>= 4.0.1)
rspec-rails
rubocop-rails-omakase
Expand Down
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Uploadcare Rails Example app

This example project demonstrates the uploadcare-rails capabilities.
The project is based on Ruby 3.3.0, Rails 7.1 and PostgreSQL.
The project is based on Ruby 3.3.0, Rails 7.1, PostgreSQL and MongoDB.

---
**NOTE**
Expand Down Expand Up @@ -100,11 +100,11 @@ Then install gems:
$ bundle install
```

After gems are installed, set your PostgreSQL credentials(env vars POSTGRES_USERNAME, POSTGRES_PASSWORD) and create a new local database:
After gems are installed, set your PostgreSQL credentials(env vars POSTGRES_USERNAME, POSTGRES_PASSWORD), setup MongoDB and create a new local database:

```console
$ rake db:create
$ rake db:migrate
$ rails db:create
$ rails db:migrate
```

Now, you can run the rails server:
Expand Down Expand Up @@ -360,6 +360,22 @@ To create a new post, click on the `Create a post` button. The post form will be

![Create a post](./references/create-post.png)

### Comments section (Mongoid ORM)

This section of the application made to demonstrate view helpers that allow to place Uploadcare File Uploader widget to a Rails view. The app has a model called Comment and having fields `title:String`, `logo:String` and `attachments:String`. Logo and attachments represent `Uploadcare::File` and `Uploadcare::Group` respectively. The model uses Mongoid ORM.

Index page for comments shows a list of comments. Each list item has `edit/delete` actions.
![Comments list](./references/comments-list.png)

Clicking on title will direct you to the `show` page of a comment.
![Show comment](./references/show-comment.png)

To create a new comment, click on the `Create a comment` button. The comment form will be opened. The form contains a text field for comment title, one File Uploaders — for comment's logo and one — for comment's attachments. These File Uploaders differ from each other by the `multiple` option. For logo it is `false`, and for attachments — `true`.
![Create a comment](./references/create-comment.png)

Edit a comment: click on the `Edit` button on the `show` page of a comment. The form will be opened. You can change the title, logo and attachments of the comment.
![Edit a comment](./references/edit-comment.png)

## Useful links
* [Uploadcare documentation](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-rails)
* [Upload API reference](https://uploadcare.com/api-refs/upload-api/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-rails)
Expand Down
59 changes: 59 additions & 0 deletions app/controllers/comments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

class CommentsController < ApplicationController
def index
@comments = Comment.order("created_at DESC")
end

def new
@comment = Comment.new
end

def edit
find_comment
end

def show
find_comment
@attachments = Uploadcare::GroupApi.get_group(@comment.attachments.load.id)["files"] if @comment.attachments
end

def create
@comment = Comment.new(comment_params)
if @comment.save
flash[:success] = "Comment has been successfully created!"
redirect_to comment_path(@comment)
else
flash.now[:alert] = @comment.errors.full_messages.join("; ")
render :new
end
end

def update
find_comment
if @comment.update(comment_params)
flash[:success] = "Comment has been successfully updated!"
redirect_to comment_path(@comment)
else
flash.now[:alert] = @comment.errors.full_messages.join("; ")
render :edit
end
end

def destroy
find_comment
@comment.destroy
flash[:success] = "Comment has been successfully deleted!"
redirect_to comments_path
end

private

def comment_params
params.require(:comment).permit(:content, :image, :attachments)
end

def find_comment
@comment = Comment.find(params[:id])
end
end
13 changes: 13 additions & 0 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class Comment
include Mongoid::Document
include Mongoid::Timestamps

field :content, type: String
field :image, type: String
field :attachments, type: String

mount_uploadcare_file :image
mount_uploadcare_file_group :attachments
end
21 changes: 21 additions & 0 deletions app/views/comments/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<%= form_tag(path, method: method) do %>

<div class="mb-3">
<label class="mb-0">Content</label>
<%= text_field_tag :content, local_assigns[:comment_content], name: 'comment[content]', class: 'form-control' %>
</div>

<div class="mb-3">
<label class="mb-0">File image</label><br>
<%= uploadcare_uploader_field :comment, :image, class: 'mb-3' %>
</div>

<div class="mb-4">
<label class="mb-0">File attachments</label><br>
<%= uploadcare_uploader_field :comment, :attachments %>
</div>

<div>
<%= submit_tag 'Save', class: 'btn btn-primary' %>
</div>
<% end %>
7 changes: 7 additions & 0 deletions app/views/comments/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h1>Edit comment</h1>

<div class="card">
<div class="card-body border">
<%= render 'comments/form', path: comment_path(@comment), method: :patch, comment_content: @comment.content %>
</div>
</div>
17 changes: 17 additions & 0 deletions app/views/comments/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<h1>Comments</h1>

<% if @comments.present? %>
<% @comments.each do |comment| %>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div class="text-place flex-grow-1 text-truncate">
<%= link_to comment.content, comment_path(comment) %>
</div>
<div class="btn-group" role="group" aria-label="Actions">
<%= link_to 'Edit', edit_comment_path(comment), class: "btn btn-secondary btn-sm" %>
<%= link_to 'Delete', comment_path(comment), method: :delete, class: "btn btn-danger btn-sm" %>
</div>
</li>
<% end %>
<% else %>
<span>No comments found. Please, create a one <%= link_to 'here', new_comment_path, class: 'd-inline' %>!</span>
<% end %>
7 changes: 7 additions & 0 deletions app/views/comments/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h1>Create a new comment</h1>

<div class="card">
<div class="card-body border">
<%= render 'comments/form', path: comments_path, method: :post %>
</div>
</div>
51 changes: 51 additions & 0 deletions app/views/comments/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<h1>
Comment "<%= @comment.content %>"
<div class="d-inline mr-0">
<%= link_to 'Edit', edit_comment_path(@comment), class: "btn btn-secondary" %>
<%= link_to 'Delete', comment_path(@comment), method: :delete, class: "btn btn-danger" %>
</div>
</h1>

<h4 class="d-flex justify-content-between align-items-center mt-5">
Image
</h4>
<% if @comment.image? %>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div class="text-place flex-grow-1 text-truncate">
<%= link_to @comment.image.load.original_filename, file_path(@comment.image.uuid) %>
<br>
<div class="badge badge-secondary"><%= @comment.image.uuid %></div>
<div class="badge badge-secondary"><%= @comment.image.mime_type %></div>
</div>
<div class="btn-group" role="group" aria-label="Actions">
<%= link_to 'Copy', copy_file_path(@comment.image.uuid), method: :post, class: "btn btn-secondary btn-sm" %>
<%= link_to 'Store', store_file_path(@comment.image.uuid), method: :post, class: "btn btn-secondary btn-sm" %>
<%= link_to 'Delete', file_path(@comment.image.uuid), method: :delete, class: "btn btn-danger btn-sm" %>
</div>
</li>
<% else %>
--
<% end %>

<h4 class="d-flex justify-content-between align-items-center mt-4">
Attachments
</h4>
<% if @attachments.present? %>
<% @attachments.each do |file| %>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div class="text-place flex-grow-1 text-truncate">
<%= link_to file.original_filename, file_path(file.uuid) %>
<br>
<div class="badge badge-secondary"><%= file.uuid %></div>
<div class="badge badge-secondary"><%= file.mime_type %></div>
</div>
<div class="btn-group" role="group" aria-label="Actions">
<%= link_to 'Copy', copy_file_path(file.uuid), method: :post, class: "btn btn-secondary btn-sm" %>
<%= link_to 'Store', store_file_path(file.uuid), method: :post, class: "btn btn-secondary btn-sm" %>
<%= link_to 'Delete', file_path(file.uuid), method: :delete, class: "btn btn-danger btn-sm" %>
</div>
</li>
<% end %>
<% else %>
--
<% end %>
11 changes: 11 additions & 0 deletions app/views/layouts/_menu.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,15 @@
<li class="nav-item">
<%= link_to 'Create a post', new_post_path, class: "nav-link #{controller_name == 'posts' && action_name == 'new' ? 'active' : ''}" %>
</li>

<li class="dropdown-divider"></li>
Mongoid example:
<li class="dropdown-divider"></li>

<li class="nav-item">
<%= link_to 'Comments', comments_path, class: "nav-link #{controller_name == 'comments' && %w[index show].include?(action_name) ? 'active' : ''}" %>
</li>
<li class="nav-item">
<%= link_to 'Create a comment', new_comment_path, class: "nav-link #{controller_name == 'comments' && action_name == 'new' ? 'active' : ''}" %>
</li>
</ul>
2 changes: 1 addition & 1 deletion bin/rails
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path("../config/application", __dir__)
require_relative "../config/boot"
require "rails/commands"
require "railsmdb/commands"
4 changes: 4 additions & 0 deletions bin/railsmdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path("../config/application", __dir__)
require_relative "../config/boot"
require "railsmdb/commands"
26 changes: 26 additions & 0 deletions config/initializers/mongoid.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require "mongoid"

Mongoid.configure do
target_version = "9.0"

# Load Mongoid behavior defaults. This automatically sets
# feature flags (refer to documentation)
config.load_defaults target_version

# It is recommended to use config/mongoid.yml for most Mongoid-related
# configuration, whenever possible, but if you prefer, you can set
# configuration values here, instead:
#
# config.log_level = :debug
#
# Note that the settings in config/mongoid.yml always take precedence,
# whatever else is set here.
end

# Enable Mongo driver query cache for Rack
# Rails.application.config.middleware.use(Mongo::QueryCache::Middleware)

# Enable Mongo driver query cache for ActiveJob
# ActiveSupport.on_load(:active_job) do
# include Mongo::QueryCache::Middleware::ActiveJob
# end
Loading

0 comments on commit 0f8d7fd

Please sign in to comment.