problems after paperclip adding a image to controller - ruby

I've got a problem updating the params of a model after adding a picture to the model.
Model is user, I've added a image to the user model with paperclip.
When I upload a picture with paperclip it is stored correctly in filesystem and in Database, but after that I can't change any other param of the user.
Thats the method how I update the attributes
def settings
#usergroups = User.find(session[:user_id]).user_groups
if request.post?
if #user.update_attributes(params[:user])
flash[:notice] = t("flash.saved")
end
end
end
Thats the method for uploading the image
def uploadimage
if request.post?
#user = User.find(params[:userid])
if #user.update_attribute(:image, params[:upload][:image])
flash[:notice] = t("flash.saved")
redirect_to :action => :settings
end
end
end
If the picture is stored in db it looks like this in user table:
Model has this:
has_attached_file :image,
:path => ":rails_root/public/uploads/:id/:filename",
:url => "/uploads/:id/:filename"
UPDATE
validates_attachment :image, :content_type => { :content_type => "image/jpg" }
Picture upload form and other attributes form are two different forms.
Does someone have an Idea whats going wrong?
problem comes from:
validates_attachment :image, :content_type => { :content_type => "image/jpg" }
is there a possibility to only validate if :image attribute is changed?

Related

How to implement "change your profile picture" feature (server side)

Im trying to implement a feature on my project, so users can change their profile picture. I'm currently at the point where everything on the front end works (when you hover the mouse over the image it shows camera and when you click it, you can browse through your computer to select an image file) Yet, it doesnt work after that point.
I'm not really sure how to handle server request.
FYI
im using routes.rb and controller .rb files to handle backend.
Also,
should i use iframe, instead of form tag in html?
Thanks!
You don't need an iFrame. Simple form-for ruby helper will help in this case. I will suggest you to use a file-uploading gem like paperclip.
Create a model for your records:
class User < ActiveRecord::Base
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
(I am supposing the model name to be user)
Create a new migration with generator:
rails generate paperclip user avatar
Update your html form as follow:
<%= form_for #user, :url => users_path, :html => { :multipart => true } do |form| %>
<%= form.file_field :avatar %>
<% end %>
Then do following changes in the controller:
def create
#user = User.create( user_params )
end
private
def user_params
params.require(:user).permit(:avatar)
end
To display image anyware on the page use the following helper:
<%= image_tag #user.avatar.url %>
This is the easiest way to handle image uploading at server side in rails. You can read more at the paperclip github page.If you don't want to use a gem then then there is a ruby class FileUtils which can help you in achieving same goal.

save images using paperclip without view

I'm using Paperclip to save images from my current local app directory. I have used two models to save images.
business.rb
class Business < ActiveRecord::Base
# Associations
has_attached_file :logo, :styles => {:thumb => "100x100>"}
validates_attachment :logo,
:size => {:in => 1..1500.kilobytes}
end
image.rb
class Image < ActiveRecord::Base
has_attached_file :data, :styles => { :thumb => '100x100>', :medium => '240x240>' }
end
when i try to save image it is not working for me like below.
Business.create(:logo => Image.first.url)
and i have this error
Paperclip::AdapterRegistry::NoHandlerError: No handler found for "/system/images/data/000/000/177/medium/error.png"
while "Image.first.url" give me this path
"/system/images/data/000/000/177/medium/error.png"
How i can do this?
Thanks
You are assigning a String(url of first image) to logo, try reading image content for url and assign it to logo.Try this!
image = open(Image.first.url).read
Business.create(logo: image)

Paperclip attachment column in database is empty

I have installed paperclip and imagemagick,and implemented the code to my model and view file.
I have a database column named 'picture' and it is empty no matter if i uploaded a picture or not. the picture acctually exists in the/public/system/decks/pictures/000/000/019/medium folder. i can see all of the uploaded pictures there, but i can't show them cause the database is empty.
My model:
class Deck < ActiveRecord::Base
attr_accessible :picture
has_attached_file :picture, :styles => { :medium => "300x300>", :thumb => "100x100>" }
attr_accessor :picture_file_name
attr_accessor :picture_content_type
attr_accessor :picture_file_size
attr_accessor :picture_updated_at
My view:
<%= form_for #deck,:url => decks_path, :html => { :multipart => true } do |f| %>
<%= f.file_field :slika %>
My migration:
class AddAttachmentPictureToDecks < ActiveRecord::Migration
def change
add_column :decks, :picture, :attachment
end
end
So i get the picture in that folder that i have mentioned before but the picture column in my decks table is empty. I can't get the picture with <%= image_tag #deck.picture.url(:medium) %>, cause my #deck.picture.url holds a /pictures/original/missing.png, my #deck.picture.path and my #deck.picture.picture_file_name also shows nothing.
Thank you.
in the end it looks like i mixed the old syntax and the new one and i couldn't get the fields right in the database. and it looks like the attr_accessors are unneccessary

Updating (Hiding) a group of objects in Rails 3

I've some difficulty in determining any way to update my objects as a group. I have an Alert model which has some alerts for the user. I'd like to provide a way to update them in bulk, as I've noticed that I often want to. I just don't know Rails well enough to know what 'the Rails way' would be.
My controller:
class AlertsController < ApplicationController
def index
#alerts = Alert.all(show: true)
end
def destroy
alert = Alert.get(params[:id])
## I lied, I'm not really deleting things, just hiding them from showing
alert.update(show: false) if alert
respond_to do |format|
format.js { render :nothing => true }
end
end
I've been using this code in my *.html.haml view to create the delete link for each individual alert:
- #alerts.each do |alert|
%span{ :class => 'description' }=alert.description
= link_to "Destroy", alert, :confirm => "Are you sure", :method => :delete, :remote => :true
What I want to have is a link on my index page Delete All which I could use to hide(update) all of the alerts. I've been attempting this with a destroy_all method for my controller, but I felt like it wasn't quite the right approach, as I didn't know how to link to something like that. Thank you for pointing me in the right direction.
Here is the destroy_all method I'd hacked together, for reference.
def destroy_all
#alerts.each do |alert|
alert.update(show: false) if alert
respond_to do |format|
format.js {render :nothing => true}
end
end
end
I don't know how you have routed to this controller but I would probably do something like this:
#routes.rb
resources :alerts do
delete :remove_all, :on => :collection
end
This will create a route looking like /alerts/remove_all which can only be called through the DELETE protocol. By specifying :collection it tells the routing the this route is not a sub route to one specific Alert so no :id is included.
Then the controller action could probably look something like this:
def remove_all
Alert.update_all({ show: false }, { show: true })
respond_to do |format|
format.js {render :nothing => true}
end
end
The update_all function will make sure that there is only one database update instead of one for each alert that is to be removed. The first argument is a hash containing the updates and the second argument is a hash with the conditions for which records are to be updated.
And from the view you should be able to link to the action like this:
= link_to "Remove All", remove_all_alerts_path, :confirm => "Are you sure", :method => :delete, :remote => :true
remove_all_alerts_path is a path helper that is automatically generated when you use the above syntax in routes.rb

Form behavior posting nested resource

I am using Ruby on Rails 3 and I would like to change its conventional behavior on posting a form in order to post from a signup action to the create action instead that from the new action. That is, I would like to use the signup action instead of the (conventional) new action in my User controller and trigger the create action to save my model data that contains nested resources.
In my /config/routes.rb file I have:
resources :users do
collection do
get 'signup'
end
resource :profile
end
In my /app/controllers/users_controller.rb I have
class UsersController < ApplicationController
def signup
#signup_user = User.new(params[:user])
#signup_user.build_profile # NOTE: Nested resource
...
end
def create
...
#signup_user.save
respond_to do |format|
format.html { render :action => :signup } # signup.html.erb
end
end
end
In my /app/views/users/signup.html.erb file I have
<%= form_for #signup_user do |f| %>
...
<% end %>
My problem is that if I submit the above form, I will be redirected to the index action of the user controller and not to the create action I expect. It seams that the form posts only to the index action.
How can I solve the problem?
I tryed to use the following
<%= form_for( :user, #signup_user, :url => { :controller => "users", :action => "create" }, :html => { :method => :post } do |f| %>
but I have still the problem: I am redirected to the index action.
SOLUTION
The problem did seam to be in the routers.rb. The correct code was
resources :users do
collection do
get 'signup'
post 'create'
end
resource :profile
end

Resources