This is a tutorial about using nested_forms gem with dropbox-paperclip plugin on Heroku to create a multiple photo upload albums interface with twitter bootstrap
Demo application :
Gems used :
- https://github.com/ryanb/nested_form
- https://github.com/janko-m/paperclip-dropbox
- https://github.com/seyhunak/twitter-bootstrap-rails
Step 1 : Create a new rails app and add the gems to Gemfile.
- paperclip
- paperclip-dropbox
- nested_form
- rails g model User name:string
- rails g model Album name:string user_id:integer
- rails g model Photo tags_name:string album_id:integer
- in app/models/user.rb :
has_many :albums, :dependent => :destroy
accepts_nested_attributes_for :albums
attr_accessible :name, :albums_attributes
validates_presence_of :name
- in app/models/album.rb
belongs_to :user
has_many :photos, :dependent => :destroy
accepts_nested_attributes_for :photos, :allow_destroy => true
attr_accessible :name, :photos_attributes
validates_presence_of :name
- in app/models/photo.rb
belongs_to :album
attr_accessible :avatar, :tags_name
has_attached_file :avatar,
:storage => :dropbox,
:dropbox_credentials => "#{Rails.root}/config/dropbox.yml",
:styles => { :thumb => "100x100" },
:dropbox_options => {
:path => proc { |style| "#{style}/#{id}_#{avatar.original_filename}"}
}
validates_presence_of :avatar
Step 4 : Adding a controller and a few actions
- rails g controller Users
- add following code to the controller
def index
@users = User.all
end
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
redirect_to root_url
else
redirect_to root_url
end
end
def show_albums
@albums = Album.find(params[:id])
end
def destroy
@user = User.find(params[:id])
@user.destroy
redirect_to root_url
end
Step 5 : Adding routes to routes.rb
resources :users do
member do
get 'show_albums'
end
end
root :to => 'users#index'
Step 6 : Creating views for forms and data show
- index.html.erb
- new.html.erb
- show_albums.html.erb
- _album_fields.html.erb
- _photo_fields.html.erb
Step 7 : Adding form html to views
in index.html.erb :
<%= link_to 'New User', new_user_path , :class => 'btn btn-medium btn-primary pull-right'%>
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Album Names</th>
<!--th>Tags</th-->
<th>Destroy</th>
</tr>
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td>
<% (user_albums_link user).each do |album_link| %>
<%= album_link.html_safe %>
<% end %>
<% thumbnails = show_photo_thumbnails(user.albums) if user.albums %>
<% if thumbnails %>
<% thumbnails.each do |thumb| %>
<%= thumb.html_safe %>
<% end %>
<% end %>
</td>
<!--td>
<%#= tags user.albums %>
</td-->
<td>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
user_path(user),
:method => :delete,
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-mini btn-danger' %>
</td>
</tr>
<% end %>
</table>
<br />
in new.html.erb :
<%= nested_form_for @user, :html => { :multipart => true } do |f| %>
<div class="controls">
Username :
<%= f.text_field :name, :class => 'text_field' %>
</div>
<%= f.fields_for :albums %>
<%= f.link_to_add "Add an album", :albums %>
<br />
<br />
<div class="controls">
<%= f.submit nil, :class => 'btn btn-primary' %>
</div>
<% end %>
in _album_fields.html.erb :
<div class="controls">
Album Name :
<%= f.text_field :name, :class => 'text_field' %>
<%= f.link_to_remove "Remove this album" %>
<%= f.fields_for :photos %>
<p>
<%= f.link_to_add "Add a photo", :photos %>
</p>
</div>
in _photo_fields.html.erb :
<div class="controls offset1">
File :
<%= f.text_field :tags_name %>
<%= f.file_field :avatar %>
<%= f.link_to_remove "Remove this photo" %>
</div>
in show_albums.html.erb :
<% thumbnails = get_photos(@albums) if @albums %>
<% if thumbnails %>
<% thumbnails.each do |thumb| %>
<%= thumb.html_safe %>
<% end %>
<% end %>
<%= show_tags @albums %>
Step 8 : Add dropbox.yml in config folder with following data :
app_key: <%= ENV["DROPBOX_APP_KEY"] %>
app_secret: <%= ENV["DROPBOX_APP_SECRET"] %>
access_token: <%= ENV["DROPBOX_ACCESS_TOKEN"] %>
access_token_secret: <%= ENV["DROPBOX_ACCESS_TOKEN_SECRET"] %>
user_id: <%= ENV["DROPBOX_USER_ID"] %>
These variables are Environment variables in environments files.
For detailed setup for paperclip-dropbox gem visit
https://github.com/janko-m/paperclip-dropbox
Step 9 : Setup Twitter Bootstrap
rails generate bootstrap:install lessStep 10 : Run the application :
rails g bootstrap:layout application fixed
bundle
rake db:create
rake db:migrate
rails s
-----------------------------------------------------------------------------------------------------------------------Thanks
Hello, thanks for u tuto.
ReplyDeleteI'm new in this mette. you have posted the code on github or other? would be very useful for learning....
I get this error when I try create a new user with albums and photos...
Deletemaybe u know whats is this:
:app_key credential is nil
Thanks again. =D
please register the app on dropbox site to get the API key
ReplyDelete