Carrierwave Rails 4 param is missing or the value is empty: image validates_presence model - validation

I'm trying to figure out uploading pictures, followed a tutorial on how to do so, and now I am augmenting it for my future needs.
My issue, that I am trying to create a model where the only thing you do is upload a picture, but if you hit save and the picture isn't present, then you stay where you are and are given an error warning.
The error message I am getting is this:
ActionController::ParameterMissing in ImagesController#create
param is missing or the value is empty: image
Extracted source (around line #72):
70
71
72
73
74
# Never trust parameters from the scary internet, only allow the white list through.
def image_params
params.require(:image).permit(:image, :remove_image)
end
end
So I acknowledge that I did a somewhat confusing thing here, naming one of the columns the same thing as my model, so here is my code:
image.rb i.e. Image Model:
class Image < ActiveRecord::Base
mount_uploader :image, ImageUploader
validates_presence_of :image
validate :image_size_validation
validates :image, presence: true
private
def image_size_validation
errors[:image] << "should be less than 500KB" if image.size > 0.5.megabytes
end
end
Image Controller, just the create method:
def create
#image = Image.new(image_params)
respond_to do |format|
if #image.save
format.html { redirect_to #image, notice: 'Image was successfully created.' }
format.json { render :show, status: :created, location: #image }
else
format.html { render :new }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
I assumed the validates :image, presence: true would fix my issue, but here I am asking for help. This is my first time trying to upload pictures/files, so whatever help you are able to give me is appreciated.
Thanks

I've had a similar issue. Changing the column name to something different than the table name fixed this for me. Don't for get to change it in the strong params and where you mount the uploader. If that doesn't work, you should share the code for your form.

Related

problems after paperclip adding a image to controller

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?

Update multiple files upload with CarrierWave

I have implemented the "multiple file uploads" in my model just like explained in the documentation of CarrierWave and it's working just fine. My problem is that I can't get the model update working. When I try to add new files it removes the old ones. I'd like to keep both. Here is part of my model and controller:
class Album < ActiveRecord::Base
mount_uploaders :photos, PhotosUploader
end
class AlbumController < ApplicationController
def create
#album = Album.new(album_params)
if #album.save
flash[:success] = 'Album created'
redirect_to #album
else
render 'new'
end
end
def update
#album = Album.find(params[:id])
if #album.update_attributes(album_params)
flash[:success] = 'Album created'
redirect_to #album
else
render 'edit'
end
end
private
def album_params
params.require(:album).permit({ photos: [] })
end
end
I thought about putting the photos in a different model but if I could make it work this way would be better. Any suggestions?
I have the below in my update method to ensure existing images (avatars) uploaded by CarrierWave remain in tact. I have a separate method that allows users to individually delete images.
def update
project_params_holder = project_params
project_params_holder[:avatars] += #project.avatars if project_params_holder[:avatars]
respond_to do |format|
if #project.update(project_params_holder)
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end

Rails: Submitting an array of child elements

I'm trying to submit a form which is supposed to have an array of child elements. I'm not sure if I have it correctly. Can somebody help me refactor?
I have a couple of models user and item. A userhas_many :items.
The form that sends the information for user and items look like the following -
<%= form_for(#user) do |f| %>
<% f.text_field :name %>
<% f.fields_for :items do |item| %>
<% item.text_field :name %>
<% item.text_field :price %>
<% end %>
<% end %>
I have the following in my controller -
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
#items = #user.items.build(item_params)
if #items.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
end
format.html { redirect_to #user, notice: 'User was successfully created. But there was a problem saving the items.' }
else
format.html { render action: 'new' }
format.json { render json: #userd.errors, status: :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:name)
end
def item_params
params.require(:user).require(:item).permit(:name, :price)
end
When I save the user, only 1 record of items get saved, meaning - the data isn't being passed as an array of objects. How do I get this to work?
It looks like right now you are only ever telling Rails to build one item object. Your form is passing up the two parameters for an item, and in your controller you call build once, so #items is only ever set equal to the single Item returned by build. Unless their are hidden parts of your form you aren't showing, it looks like you're only setting one set of options for a user's items. If your goal is to have an array of many items with identical parameters, the fastest fix would be to just do this within the logic of your create action. There are many ways you could implement that (here is one simple way):
#items = []
x.times { #items << #user.items.build(item_params) }
If you're looking to send a request from the form with multiple unique items, you'll have to add more fields to your form, since currently you are only sending one set of parameters.
There are few corrections to be made in your code.
In your users_controller
def new
#user = User.new
3.times do #this will generate three records of items
#user.items.build
end
end
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
else
format.html { render action: 'new' }
format.json { render json: #userd.errors, status: :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:name,items_attributes: [:name,price])
end

Using link_to remote: true to pass parameters to rails

So I have a page with several messages, each with a link that changes (refines) the RATING of that message. When a user clicks on this link, I want an AJAX call that updates the corresponding column value in the database for that message. When this link is clicked, nothing should happen visibly. There should be no page refresh or reload.
I've been trying to do this using link_to remote: true, but I can't seem to get it to work. Documentation online is fairly unclear on this question and with the changes between Rails 2 and 3, some things like :with are no longer supported.
I've copied what I have so far, but I know its far from even coming close to a solution.
In terms of parameters I need passed into the database, I need the profile_id, the message_id and the new_rating.
Thanks in advance!
show.html.haml
.status-bar
= link_to "", { action: :refine_result }, remote: true
profile_controller.rb
...
def refine_result
#refinement = ResultRefinement.new
#refinement.profile_id = params[:profile_id]
#refinement.message_id = params[:message_id]
#refinement.save
respond_to do |format|
format.html { render nothing: true }
format.js { render nothing: true }
end
end
result_refinement.rb
class ResultRefinement < ActiveRecord::Base
attr_accessible :profile_id, :message_id, :new_rating, :deleted
belongs_to :profile
end
You need to set up a route for ProfileController#refine_result first. Something like
match '/profile/refine_results' => 'profile#refine_results', :as => 'refine_results'
Then you can use
.status-bar
= link_to "", refine_results_url(profile_id: 1, message_id: 100, new_rating: "awful"), remote: true

Best practice for Rails controller that paginates one mime format but not another

My rails project is paginating the HTML format but not the the others. Can someone suggest a more elegant approach to dealing with the difference in getting the #contacts collection? Perhaps the pagination version should be a different method that only supports HTML?
def index
if request.format.to_sym == :html
#contacts = Contact.paginate(page: params[:page]).search(params[:search])
else
#contacts = Contact.search(params[:search])
end
respond_to do |format|
format.html { render html: #contacts }
format.mobile { render mobile: #contacts }
format.json { render json: #contacts }
format.xml { render xml: #contacts.to_xml }
end
end
My solution was to add paginate as a RESTful resource in routes.rb which automagically gives me the route helper method: paginate_contacts_path
resources :contacts do
collection do
get 'paginate'
end
end
and to have a separate paginate method in ContactsController
def index
#contacts = Contact.search(params[:search])
respond_to do |format|
format.html { render html: #contacts }
format.mobile { render mobile: #contacts }
format.json { render json: #contacts }
format.xml { render xml: #contacts.to_xml }
end
end
def paginate
#contacts = Contact.paginate(page: params[:page]).search(params[:search])
respond_to do |format|
format.html
end
end
Strongly prefer a separate method because this creates inconstancies and makes the piece less testable. Also you would, in for example documentation, need to create exceptions.
Another way is to handle this with some parameter. Now it suddenly (when you only change views) returns different data. That might look like an error for an unknown developer and might raise issues.
So don't do it magically, clear parameter or separate method.

Resources