I am trying to upload an image in my Rails Application. However, I am unable to do so. I am relatively new to rails and I need some help here.
I have a "Picture" Model shown here -
class Picture < ActiveRecord::Base
attr_accessible :photo, :tag
has_attached_file :photo, :styles => { :medium => "300x300>",
:large => "1000x1000>", :thumb => "100x100>" }
end
I have a "Pictures" Controller shown here -
class PicturesController < ApplicationController
def new
#picture = Picture.new
end
def create
#picture = Picture.create( params[:picture] )
if #picture.save
flash.now[:success] = "Image Uploaded"
redirect_to #picture
else
render 'new'
end
end
def index
end
def show
#picture = Picture.find(params[:id])
send_data #picture.photo, :type => 'image/png', :disposition => 'inline'
end
def imageshow
end
end
Lastly, These are my "new" and "show" views:
"new.html.erb"
<h1>Upload an Image</h1>
<div>
<%= form_for(#picture, :html => {:multipart => true}) do |f| %>
<%= f.file_field :photo %>
<%= f.label :tag %>
<%= f.text_field :tag %>
<%= f.submit "Submit", class: "btn btn-large btn-primary" %>
<% end %>
</div>
"show.html.erb"
<h1>Displaying Uploaded Image</h1>
<div>
<%= image_tag #picture.photo.url %>
<%= image_tag #picture.photo.url(:large) %>
</div>
I am able to reach the Upload page (ie, new.html.erb in Pictures Controller). However, when I upload an image I get the following error:
"This image "http://10.102.119.20:3000/pictures/12" cannot be displayed because it contains errors"
My queries are:
Where does an image get uploaded on the server?
Is there any configuration that needs to be done?
Is there any other issue with my code?
Thanks in advance for any help..!!
Ryan Bates discusses Paperclip in his Railscasts. Check it out. It helped me get started.
Related
Sorry for maybe newbie question.
I want to use a paperclip and paperclip_database gems to attach and save files in my database.
But I stuck on sending file's data from views to controller.
I've done all from this, and this resources. As the result I have next models:
class User < ActiveRecord::Base
has_many :certificates, :dependent => :destroy
accepts_nested_attributes_for :certificates, :allow_destroy => true
end
class Certificate < ActiveRecord::Base
belongs_to :user
attr_accessor :image
has_attached_file :image,
:storage => :database,
:database_table => 'image_files',
:cascade_deletion => true
end
in a controller
Users_controller
def new
#user = User.new
#user.certificates.build
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~
end
def create
#user = User.new(params[:user])
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~
end
end
and my view form is:
<%= form_tag #user, method: :put, :html => { :multipart => true } do |f|%>
<%= fields_for each_event_entry.certificates.first do |c| %>
<tr>
<th>Certificate</th>
<td>
<%= c.file_field :image %>
</td>
</tr>
<% end %>
<% end %>
But when I attach a file and try to submit, I've only got a file name in params:
{
"user" => {"some"=>"params"}
"certificate"=>{"image"=>"IMG_1642.JPG"}
}
And certificate is saved whithout attached file.
Any help will be extremely appreciated.
Finally, I found out the problem.
It appears to be that the "form_tag" form doesn't need an :html attribute, so the html form should look like:
<%= form_tag #user, :multipart => true do |f| %>
In my case, there is no necessity of method: as well.
Hope this will help someone.
I am trying to embed a video in my app and am using the gem panda '1.6.0' for this. I followed the pandastream integrate with rails guide and have the following code:
controllers:
-------------
class BoothVideosController < ApplicationController
before_filter :init_booth_video
def show
#original_video = #video.panda_video
#h264_encoding = #original_video.encodings["h264"]
render :template => 'booth_video/booth_video', :layout =>
'sponsored_group_manage_sub_menu'
end
def new
#video = BoothVideo.new
render :layout => 'sponsored_group_manage_sub_menu'
end
def create
#video = BoothVideo.create!(params[:video])
redirect_to :action => :show, :id => #video.id
end
def init_booth_video
#group = Group.find(params[:group_id])
#video=#group.booth_video
end
end
class PandaController < ApplicationController
def authorize_upload
payload = JSON.parse(params['payload'])
upload = Panda.post('/videos/upload.json', {
file_name: payload['filename'],
file_size: payload['filesize'],
profiles: "h264",
})
render :json => {:upload_url => upload['location']}
end
end
model:
------
class BoothVideo < ActiveRecord::Base
belongs_to :group
validates_presence_of :panda_video_id
def panda_video
#panda_video ||= Panda::Video.find(panda_video_id)
end
end
View
-----
<% content_for(:page_title, "Create a New Booth Video") -%>
<% form_for(:booth_video,:url => group_booth_video_path, :html => {:id =>
"new_booth_video", :multipart => true}) do |f| %>
<h5>New Booth Video</h5>
<fieldset>
<input type="hidden" name="panda_video_id"/>
<label for="title">Title</label><br />
<%= f.text_field :title, :size => 32, :placeholder => "Title for the new booth
video" %><br /><br />
<div class='progress'>
<span id="progress-bar" class='bar'></span>
</div>
<div id="browse">Choose file</div>
<%=f.submit "Upload video" %>
<% end %>
I have also included the js for panda uploader in my application.js file.
I am able to see my file uploader but when I actually browse and select a file, it does not actually get loaded - also no progress is indicated in the progress bar.
Why is the video not getting uploaded?
The create action mentions params[:video] in the tutorial but there is no param in the
'new' form for the uploaded video-how will it recognize this?
Please help! Thanks in advance...
I followed the tutorial screencast over here: http://www.emersonlackey.com/article/rails-paperclip-multiple-file-uploads. I want my model have multiple pictures upload show up.
I have examined carefully every steps, the most common issue is forget to add assets_attributes to attr_accessible, I have done that. Another issues might bbe forgot to add ID to asset model, i done that too. However, I still have trouble understanding why it happen.
Can't mass-assign protected attributes: asset in app/controllers/posts_controller.rb:24:in `update'
I have already add list of all attributes for a Post to post model. Like:
class Post < ActiveRecord::Base
attr_accessible :name, :content, :assets_attributes
validates :user_id, presence: true
belongs_to :user
has_many :assets
accepts_nested_attributes_for :assets, :allow_destroy => true
default_scope order: 'posts.created_at DESC'
end
Here is the post_controller.rb file:
def edit
#post = Post.find(params[:id])
5.times { #post.assets.build }
end
def update
#post = Post.find(params[:id])
if #post.update_attributes(params[:post])
redirect_to #post, :notice => "Post has been updated."
end
def create
post = current_user.posts.build(params[:post])
if post.save
flash[:success] = "post created success!"
redirect_to #post
else
#feed_items = []
flash[:failure] = "post created fail!"
redirect_to root_path
end
end
def new
#post = current_user.posts.new #if signed_in?
5.times { #post.assets.build }
end
Here is the template file:
<%= simple_form_for(#post, :html => {:multipart => true}) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :content %>
<%= f.text_field :content %>
<%= f.simple_fields_for :assets, :html => { :multipart => true } do |asset_fields| %>
<% if asset_fields.object.new_record? %>
<P><%= asset_fields.file_field :asset %> </P>
<% end %>
<% end %>
<%= f.simple_fields_for :assets, :html => { :multipart => true } do |asset_fields| %>
<% unless asset_fields.object.new_record? %>
<P><%= link_to image_tag(asset_fields.object.asset.url(:thumb)), asset_fields.objects.asset.url(:original) %>
<%= asset_fields.check_box :_destroy %></P>
<% end %>
<% end %>
Below is asset.rb:
class Asset < ActiveRecord::Base
belongs_to :post
has_attached_file :asset,
:style => { :large => "640x480", :medium => "300x300", :thumb => "100x100"} ,
:path => ":rails_root/public/system/posts/images/:id/:style/:filename",
:url => "/system/posts/images/:id/:style/:filename"
end
Can someone give me some hint ? Thanks a lot!
Your Asset model needs to have attr_accessible on it too - specifically for the asset field.
I hope for help to follow problem.
I have install gem rails3-jquery-autocomplete from here
and gem "acts-as-taggable-on" from here
Here is my history:
my model is
class Article <ActiveRecord::Base
acts_as_taggable_on :tags
attr_accessible :title, :body, :tag_list
my controller is
class ArticlesController < ApplicationController
autocomplete :tag, :name, :class_name => 'ActAsTaggableOn::Tag'
def tag_cloud
#tags ||=Article.tag_counts_on(:tags)
end
def all
#tags = Article.tag_counts_on(:tags).limit(8).order('count desc')
klass = Article
klass = klass.tagged_with(#tag) if (#tag = params[:tag]).present?
#articles = klass.where(:state => '4').paginate(:page => params[:page])
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #articles }
end
end
my route is
resources :articles do
collection do
get 'autocomplete_tag_name'
get 'about'
get 'all'
get 'myarticles'
delete 'destroy'
end
end
my _form.html.erb
<div class="field">
<label for="tag_list">Κατηγορία (Μπορείτε να προσθέσετε διαφορετικές κατηγορίες διαχωρίζοντάς τες με κόμμα)</label><br />
<%= f.autocomplete_field :tag_list, autocomplete_tag_name_articles_path, :"data-delimiter" => ', ' %>
</div>
my index.html.erb
<div class='tag-box'>
<% #tags.sort_by(&:count).reverse.each do |k| %>
<% url_opts = {:action => "all", :controller => "articles"}
link_name = "#{k.name} (#{k.count})" %>
<% if #tag == k.name %>
<%= link_to link_name, url_opts.merge(:tag => nil), :class => "tag current_tag", :title => "Κλικ για εμφάνιση όλων" %>
<% else %>
<%= link_to link_name, url_opts.merge(:tag => k.name), :class => "tag", :title => "Κλικ για εμφάνιση άρθρων στην κατηγορία #{k.name}" %>
<% end %>
<% end %>
</div>
my application.html.erb
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'jquery-1.7.2.min.js', 'jquery-ui-1.8.19.custom.min.js', 'autocomplete-rails.js', 'rails.js' %>
<%= stylesheet_link_tag 'jquery-ui-1.8.19.custom.css' %>
and last my Gemfile
gem 'rails', '3.0.11'
gem 'pg'
gem 'jquery-rails', '>= 1.0.12'
gem 'rails3-jquery-autocomplete'
gem 'acts-as-taggable-on', '~> 2.2.2'
in app works the tagging system but don't work the autocomplete.
perhaps my problem is on file _form.html.erb. I have on file new.html.erb the code
<section id="myarticles">
<h2>Νέο άρθρο</h2>
<%= render 'form' %>
</section>
Is about render and autocomplete together and autocomplete don't work?
Finaly the solution for my problem that can help someone with the same situation is simple.
Copy the file jquery-ui-1.8.19.custom.css from public/stylesheets/ui-lightness or from public/stylesheets/smoothness depends from the download theme from jQuery UI-Autocomplete
and paste to public/stylesheets/ and automagicaly disappeared the Routing Error and voila the Autocomplete functioning.
I had follow the instructions from here
Copy the files on the css folder to the public/stylesheets folder on your app. Note that these files may be one level down from the css folder, in a folder called "ui-lightness".
but the right position is on directory public/stylesheets.
Also remove from mycontroller the follow code :class_name => 'ActAsTaggableOn::Tag' and now the code looks like
class ArticlesController < ApplicationController
autocomplete :tag, :name
I've installed devise for my rails app, i can go to the sign in page or the sign up page. But I want them both on a welcome page...
So I've made a welcome_page_controller.rb with the following function:
class WelcomePageController < ApplicationController
def index
render :template => '/devise/sessions/new'
render :template => '/devise/registration/new'
end
end
But when i go to the welcome page i get this error:
NameError in Welcome_page#index
Showing /Users/tboeree/Dropbox/rails_projects/rebasev4/app/views/devise/sessions/new.html.erb where line #5 raised:
undefined local variable or method `resource' for #<#<Class:0x104931c>:0x102749c>
Extracted source (around line #5):
2: <% #header_title = "Login" %>
3:
4:
5: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
6: <p><%= f.label :email %><br />
7: <%= f.email_field :email %></p>
8:
Does anybody knows a solution for this problem? Thanks in advance!
Does it have to do with the fact that it is missing the resource function? in the welcome_page controller? It's probably somewhere in the devise controller...?
Regards,
Thijs
Here's how I managed to did it.
I've put a sign up form in my home#index
My files:
view/home/index.html.erb
<%= render :file => 'registrations/new' %>
helper/home_helper.rb
module HomeHelper
def resource_name
:user
end
def resource
#resource = session[:subscription] || User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
def devise_error_messages!
return "" if resource.errors.empty?
messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
sentence = I18n.t("errors.messages.not_saved",
:count => resource.errors.count,
:resource => resource_name)
html = <<-HTML
<div id="error_explanation">
<h2>#{sentence}</h2>
<ul>#{messages}</ul>
</div>
HTML
html.html_safe
end
end
You need that part because Devise works with something called resource and it should be defined so you can call your registration#new anywhere.
Like that, you should be able to register. However, I needed to display errors on the same page. Here's what I added:
layout/home.html.erb (the layout used by index view)
<% flash.each do |name, msg| %>
# New code (allow for flash elements to be arrays)
<% if msg.class == Array %>
<% msg.each do |message| %>
<%= content_tag :div, message, :id => "flash_#{name}" %>
<% end %>
<% else %>
# old code
<%= content_tag :div, msg, :id => "flash_#{name}" %>
<% end %> #don't forget the extra end
<% end %>
I found this code here
And here's something I created: I saved my resource object if invalid in a session so that the user hasn't to fill every field again. I guess a better solution exists but it works and it's enough for me ;)
controller/registration_controller.rb
def create
build_resource
if resource.save
if resource.active_for_authentication?
# We delete the session created by an incomplete subscription if it exists.
if !session[:subscription].nil?
session[:subscription] = nil
end
set_flash_message :notice, :signed_up if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
else
set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords(resource)
# Solution for displaying Devise errors on the homepage found on:
# https://stackoverflow.com/questions/4101641/rails-devise-handling-devise-error-messages
flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages
# We store the invalid object in session so the user hasn't to fill every fields again.
# The session is deleted if the subscription becomes valid.
session[:subscription] = resource
redirect_to root_path #Set the path you want here
end
end
I think I didn't forget any code. Feel free to use whatever you need.
Also, you can add your sign in form in the same page (something like that:)
<%= form_for("user", :url => user_session_path) do |f| %>
<%= f.text_field :email %>
<%= f.password_field :password %>
<%= f.submit 'Sign in' %>
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
<%= link_to "Forgot your password?", new_password_path('user') %>
<% end %>
Cheers !