Paper clip image showing up in wrong place - ruby-on-rails

Hey i have a rails app that i am uploading images with paperclip....
So i have a comic_review scaffold that i upload images of comic covers and i also have a news scaffold where i post news and images.....
When i edit news/1/edit and upload a picture the comics_review/1 picture becomes the same as the news one and vice a versa.
I checked the links in the views to make sure that i is correct and they seem to be ok...
heres my view
home.html.erb
<h2 style="color: black; font-size: 30px;"><%= #comic_review1.title %></h2>
<p><%= #comic_review1.content %></p>
<%= link_to 'Read More...', comic_review_path(#comic_review1) %>
<%= image_tag #comic_review1.photo, class: "homepage_comics" %>
news/show.html
<%= #news.author %>
<%= #news.date %>
<%= image_tag #news.photo, class: 'pull-left', style: 'margin-right: 10px;' %>
heres my controller
static_pages_controller.rb
class StaticPagesController < ApplicationController
def home
#user = current_user
#article = Article.first
#comic_review1 = ComicReview.find(1)
#comic_review2 = ComicReview.find(2)
#comic_review3 = ComicReview.find(3)
#comic_review4 = ComicReview.find(4)
end
def comics
#comic_review1 = ComicReview.find(1)
#comic_review2 = ComicReview.find(2)
#comic_review3 = ComicReview.find(3)
#comic_review4 = ComicReview.find(4)
end
def batnews
#article = Article.first
#news_all = News.all
end
end
heres my model
comic_review.rb
class ComicReview < ActiveRecord::Base
attr_accessible :content, :credits, :review, :title, :photo, :comicreview
has_attached_file :photo, :styles => { :small => '400x400' },
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => ":attachment/activities/:id/:style.:extension",
:bucket => 'goddam_batman_pics'
has_many :comments, as: :commentable, dependent: :destroy
end
news.rb
class News < ActiveRecord::Base
attr_accessible :title, :author, :date, :content, :photo
has_attached_file :photo, :styles => { :small => '400x400' },
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => ":attachment/activities/:id/:style.:extension",
:bucket => 'goddam_batman_pics'
end
controllers are your basic controllers that gets generated by the scaffold
so whenever i update a photo for news/1 the photo for comic_reviews/1 gets the same photo as the news one
any help would be appreciated thank you

I'm pretty sure the problem is that you're giving the "photo" the same name in both models. Try naming one comic_photo and the other news_photo, or alternately, explore Polymorphic Associations.
Dated Railscast link, but gives you the idea - http://railscasts.com/episodes/154-polymorphic-association
PS - Bonus points for figuring out how to load four ComicReviews in one query rather than four in those controllers.

ok so what i had to do was in my model i changed the path from
:path => ":attachment/activities/:id/:style.:extension",
to
:path => "/image/:id/:filename",
and it seems to be working

Related

Rails add separate view for child table

I'm creating a basic application where user has a profile and can upload upto 5 pictures of him/her.I created user profile page, I would want to allow the user to upload pictures in different page. Like having a link Add/Edit Photo and on clicking it to take to a different page and upon submit should redirect back to profile page and update/insert records. So I'm kind of confused should I do this under photos model/controller or member model/controller.Here is my sample code and link is below
I'm using paperclip for image upload
Member view
<%= link_to 'Add/Edit Photo' , edit_member_path(current_member.id) %>
<%= form_for(#member, :remote=> true, html: {
:multipart => true,
class:"form-light padding-15"}) do |f| %>
<%= f.label :firstname %>
<%= f.text_field :firstname, autofocus: true, :class => "form-control",:placeholder =>"FirstName" %>
<%= f.label :lastname %>
<%= f.text_field :lastname,autofocus: true, :class => "form-control",:placeholder =>"LastName"%>
<% end %>
class Member < ActiveRecord::Base
attr_accessible :firstname, :lastname, :user_id, :dob,:gender,:l_country_id,:age,
:l_state_id,:l_city,:g_country_id,:residency_status,:marital_status,
:community,:sub_community,:height,:weight,:complexion,:body_type,
:diet,:smoke,:drink,:education,:working_as,:working_with,:mobile_no,:about_yourself,:disability,:photos_attributes
has_many :photos
belongs_to :country
belongs_to :user
belongs_to :state
accepts_nested_attributes_for :photos
end
class Photo < ActiveRecord::Base
belongs_to :member
has_attached_file :data, :styles => { :thumb => "100x100#",
:medium => "500x500#",
:large => "700x700>" },
:url => "/assets/member/:id/:style/:basename.:extension",
:path => ":rails_root/public/assets/member/:id/:style/:basename.:extension"
#validates_attachment_presence :data
validates_attachment_content_type :data, :content_type => /\Aimage/
#validates_attachment_size :data, :less_than => 5.megabytes
validates_attachment_content_type :data, :content_type => ['image/jpeg', 'image/png']
attr_accessible :member_id,:data
end
As the separate pages are for photos only, my suggestion is to use PhotosController. And you can use nested resources to get the member_id from the url, if that is your concern.
http://guides.rubyonrails.org/routing.html#nested-resources

Displaying uploading buttons depending on files uploaded

I have a project model where i can create projects and to each project upload videos and photos. I'm using nested attributes. My form displays 5 photo upload buttons and 5 video upload buttons. I want to hide the buttons that are used. For example: If I've uploaded 1 photo and 2 videos I want my edit form to display 4 upload photo buttons and 3 for the videos.
Right now, if a photo is uploaded it hides 1 upload button from the photos and one from the videos. Does anyone know how to make this possible?
Here is my controller.
def new
#project = Project.new()
(5 - #project.assets.length).times { #project.assets.build }
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #project }
end
end
# GET /projects/1/edit
def edit
#project = Project.find_by_permalink(params[:id])
(5 - #project.assets.length).times { #project.assets.build }
end
Gems:
gem "paperclip", "~> 3.5"
# handels video upload
gem "paperclip-ffmpeg", "~> 1.0.0"
Project Model:
class Project < ActiveRecord::Base
has_permalink :title
default_scope :order => 'created_at desc'
attr_accessible :title, :description, :assets_attributes, :dependent => :destroy
validates_uniqueness_of :title
validates_presence_of :title
has_many :assets, :dependent => :destroy
accepts_nested_attributes_for :assets, :allow_destroy => true
end
Asset Model:
class Asset < ActiveRecord::Base
require 'paperclip'
require 'paperclip-ffmpeg'
belongs_to :project, :foreign_key => "project_id"
attr_accessible :project_id, :photo, :video
has_attached_file :photo, :styles => { :thumb => "130x130#", :medium => "300x300#", :small => "160x160#"}
has_attached_file :video, :styles => {
:mobile => {:geometry => "400x300", :format => 'flv', :streaming => true}
}, :processors => [:ffmpeg, :qtfaststart]
end
You need to differentiate the video-assets and image-assets. That will do.
Also, if you can share with us what gems are being used, we could help better.
Solved it by making a "add" button, to add a file field on request.(Did one for the video upload and one for the photo upload.)
<div class="row">
<div class="newPaperclipFiles col-md-4 col-md-offset-1" style="overflow: hidden;">
<h3 style="color:rgb(31,154,207);">Upload a Photo</h3>
<hr style="margin-left: -20%; width: 280px !important;"></hr>
<%= f.fields_for :assets do |asset_photo| %>
<% if asset_photo.object.new_record? %>
<div class="btn custumbtn btn-xs" id="duplp" onlick="duplicatep()">Add</div>
<div id="duplicaterp">
<%= asset_photo.file_field :photo %>
</div>
<% end %>
<% end %>
</div>
</div>
js:
<script type="text/javascript">
document.getElementById('duplp').onclick = duplicatep;
var i = 0;
var original = document.getElementById('duplicaterp');
function duplicatep() {
var clone = original.cloneNode(true);
clone.id = "duplicaterp" + ++i;
original.parentNode.appendChild(clone);
}
</script>

Rails - cannot display an image uploaded to Amazon S3

I have these two models:
user:
has_many :commercials, :dependent => :destroy, :inverse_of => :user
commercial:
belongs_to :user, :inverse_of => :commercials
has_attached_file :image,
:styles => { :medium => "400x400",
:thumb => "50x50>" }
I just uploaded one image, the image is successfully uploaded to Amazon S3 and saved into the database.
But how to display it?
I tried:
<%= image_tag #user.adverts(:medium) %>
or
<%= image_tag #user.adverts.medium.url %>
But none of above is working...
Not adverts, but commercials? So should it not be something like:
#user.commercials.first.image.url
Assuming foo as the name of the commercial instance
<%= image_tag foo.image.url(:medium) %>

rails 3 polymorphic association with paperclip and multiple models

I want to make polymorphic associations with paperclip, and allow my user to have one avatar and multiple images.
Attachment model:
class Attachment < ActiveRecord::Base
belongs_to :attachable, :polymorphic => true
end
class Avatar < Attachment
has_attached_file :image, :styles => { :thumb => "150x150>", :view => "260x180>" },
end
class Image < Attachment
has_attached_file :image, :styles => { :thumb => "150x150>", :view => "260x180>" },
end
User Model:
has_one :avatar, :as => :attachable, :class_name => 'Attachment', :conditions => {:type => 'avatar'}
accepts_nested_attributes_for :avatar
User Controller:
def edit
#user.build_avatar
end
User View form:
<%= form_for #user, :html => { :multipart => true } do |f| %>
<%= f.fields_for :avatar do |asset| %>
<% if asset.object.new_record? %>
<%= asset.file_field :image %>
<% end %>
<% end %>
when I attempt to save the changes I get the error => unknown attribute: avatar
if I remove the :class_name => 'attachment' in the has_one association I get the error =>
uninitialized constant User::Avatar
I need to also attach avatars to blog posts, so I need the association to be polymorphic (or atleast i think so)
I am stumped and any help would be greatly appreciated.
I do have a project in the works that is successfully using Paperclip and polymorphic associations. Let me show you what I have, and maybe you can apply it to your project:
class Song < ActiveRecord::Base
...
has_one :artwork, :as => :artable, :dependent => :destroy
accepts_nested_attributes_for :artwork
...
end
class Album < ActiveRecord::Base
...
has_one :artwork, :as => :artable, :dependent => :destroy
accepts_nested_attributes_for :artwork
...
end
class Artwork < ActiveRecord::Base
belongs_to :artable, :polymorphic => true
attr_accessible :artwork_content_type, :artwork_file_name, :artwork_file_size, :artwork
# Paperclip
has_attached_file :artwork,
:styles => {
:small => "100",
:full => "400"
}
validates_attachment_content_type :artwork, :content_type => 'image/jpeg'
end
the songs form and the albums form include this as a partial:
<div class="field">
<%= f.fields_for :artwork do |artwork_fields| %>
<%= artwork_fields.label :artwork %><br />
<%= artwork_fields.file_field :artwork %>
<% end %>
don't forget to include :html => { :multipart => true } with the form
artworks_controller.rb
class ArtworksController < ApplicationController
def create
#artwork = Artwork.new(params[:artwork])
if #artwork.save
redirect_to #artwork.artable, notice: 'Artwork was successfully created.'
else
redirect_to #artwork.artable, notice: 'An error ocurred.'
end
end
end
and finally, an excerpt from songs_controller.rb:
def new
#song = Song.new
#song.build_artwork
end
I'm not sure you really need to be polymorphic. How about this approach, which uses has_many :through? In plain English, the user has one avatar which has multiple images, and through this association you can call User.images to get the collection of images associated with the avatar.
http://guides.rubyonrails.org/association_basics.html
class User < ActiveRecord::Base
has_one :avatar
has_many :images, :through => :avatar
end
class Avatar < ActiveRecord::Base
belongs_to :user
has_many :images
end
class Image < ActiveRecord::Base
belongs_to :avatar
has_attached_file :image, :styles => { :thumb => "150x150>", :view => "260x180>" },
end
Having said all of this, I am left to wonder why you need to go through all this anyway. Why not just do
class User < ActiveRecord::Base
has_many :avatars
end
which would give you as many images (avatars) as you want.

Deleting images with paperclip

I'm trying to delete each single image uploaded for a model (work has many images) but now my code works like this: I have three images uploaded in a work, I want to delete just one but when I check the image's checkbox and submit the update action it will delete all the three images.
Here is my work model's code:
before_save :destroy_image?
belongs_to :category
has_many :images, :as => :assetable, :class_name => "Work::Image", :dependent => :destroy
accepts_nested_attributes_for :images, :reject_if => proc { |attributes| attributes['attachment'].blank? }
def image_delete
#image_delete ||= "0"
end
def image_delete=(value)
#image_delete = value
end
private
def destroy_image?
self.images.clear if #image_delete == "1"
end
end
class Work::Image < Asset
has_attached_file :attachment, :styles => {:small => "200x150>", :large => "400x300>"},
:url => "/uploads/works/:id/:style/:basename.:extension",
:path => ":rails_root/public/uploads/works/:id/:style/:basename.:extension"
end
I think the problem is that delete all images
self.images.clear if #image_delete == "1"
but I don't understand how to fix it. I hope in your help.
You should use the :allow_destroy options of accepts_nested_attributes_for instead.
And in your form something like this:
<% #work.images.each do |image| %>
<%= f.fields_for :images, image do |image_fields| %>
<%= image_tag image.url(:small) %>
<%= image_fields.check_box :_destroy %>
<% end %>
<% end %>

Resources