The problem is with "strong parameters" in rails.
I use dragonfly for uploading images.
The problem is that if I send an empty form I do not get any parameters for error handling. What can be the reason?
Controller:
There is still also a method "Create" which saves the image in the database and sends the user to a page with pictures.
def index
#gallery = Gallery.new
#galleries = Gallery.all
end
def create
#gallery = Gallery.new(gallery_params)
if #gallery.save
redirect_to galleries_path, flash: { success: 'Your Image was successfully save.' }
else
redirect_to :back, flash: { alert: "Your Image don't save." }
end
end
def gallery_params
params.require(:gallery).permit(:image)
end
Views:
= form_for #gallery do |f|
= f.file_field :image
= f.submit 'Submit', class: 'btn bth-primary btn-lg'
Parameters:
{"utf8"=>"✓", "authenticity_token"=>"8eotQtkj8SElqJLdHuOX8r+dWrCJRWTmVcyfd1mSLD/8MjWw/ElH/HCxZFSJ6oOWaxpbLbn4kAg5nlFycsgjHg==", "commit"=>"Submit"}
This is the expected behavior, see the documentation for ActionController::Parameters#require
What I usually do in those cases is catch the exception and display a flash message to notify the user. You could also manually add an error to the model.
def create
#gallery = Gallery.new(gallery_params)
if #gallery.save
redirect_to galleries_path, flash: { success: 'Your Image was successfully save.' }
else
redirect_to :back, flash: { alert: "Your Image don't save." }
end
rescue ActionController::ParameterMissing => e
redirect_to :back, flash: { alert: "Please attach an image." }
end
Related
I want to show a flash notice in my Rails app all the time unless only certain attributes are updated.
def update
if #user.update_attributes(user_params)
if user_params == [:user][:certain_params]
redirect_to users_path
else
redirect_to users_path, notice: "#{#user.name} saved."
end
else
redirect_to edit_user_path(#user), flash: { error: #user.mapped_errors }
end
end
Something like this pseudocode?
Use the changed method to get an array of the attributes that are changed, create a flash message if the attributes are not the "non-notify" attributes.
def update
#user.assign_attributes(user_params)
changed_fields = #user.changed
if #user.save
flash[:notice] = "#{#user.name} saved." if changed_fields != ["photo"]
redirect_to users_path
else
redirect_to edit_user_path(#user), flash: { error: #user.mapped_errors }
end
end
This will show the saved notice if they change photo plus other attributes, or if they change other attributes but not photo. The message is suppressed only if only photo is changed.
def update
#user = User.find(params[:id])
# lets say you have these attributes to be checked
attrs = ["street1", "street2", "city", "state", "zipcode"]
attributes_changed = (#user.changed & attrs).any?
if #user.update_attributes(user_params)
flash[:notice] = "#{#user.name} saved." if attributes_changed
redirect_to users_path
else
redirect_to edit_user_path(#user), flash: { error: #user.mapped_errors }
end
end
For more info see
Rails 3 check if attribute changed
http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
I'm trying to update an Idea attribute challenge_id through a hidden form field. Here is the field:
<%= f.hidden_field :challenge_id, :value => #challenge.id %>
It successfully passes the challenge id as a param when an idea is created to the Idea Controller#create method:
Started POST "/ideas.js" for ::1 at 2015-06-18 15:39:49 -0400
Processing by IdeasController#create as JS
Parameters: {"utf8"=>"✓", "idea"=>{"title"=>"adsf", "description"=>"asf", "domain_tokens"=>"20", "challenge_id"=>"5"}, "commit"=>"Create Idea"}
This challenge_id => 5 should then be saved to the idea in the line #idea = Idea.new(idea_params) below:
ideas_controller.rb
def create
#idea = Idea.new(idea_params)
respond_to do |format|
if #idea.save
idea_count = #idea.user.ideas_created_count
#idea.user.update(:ideas_created_count => idea_count + 1)
#idea.domains.each do |domain|
current_user.add_points(1, category: domain.title)
end
#ideas = current_user.current_team.ideas.sort_by{|i| i.heat_index}.reverse
#ideas = #ideas.paginate(:page => params[:ideas_page], :per_page => 10)
format.html { redirect_to :back, notice: 'Idea was successfully created.' }
format.json { render :show, status: :created, location: #idea }
format.js
else
format.html { redirect_to :back, notice: "You must attach domains to your Idea." }
format.json { render json: #idea.errors, status: :unprocessable_entity }
format.js { render :create_failed }
end
end
end
.
.
def idea_params
params.require(:idea).permit(:title, :description, :challenge_id)
end
However, this challenge id isn't being saved to the idea with the other permitted idea_params, :title and :description. How can I get challenge_id to be saved to the Idea when it's created?
Instead of using hidden field, why not pass in the challenge_id in your form? Otherwise, you leave open the possibility that users can enter whatever they want in that hidden field.
Form:
form_for [#challenge, Idea.new] do |f|
And then:
def create
#challenge = Challenge.find(params[:challenge_id])
#idea = Idea.new(idea_params)
#idea.challenge_id = #challenge.id
end
I'm assuming you have challenge_id column in ideas table.
Try something like:
def create
#idea = Idea.new(idea_params)
#idea.challenge_id = params[:idea][:challenge_id]
#...
end
If you params or column you want to save it to is different, make sure to make the change, but you get the idea.
I'm having trouble uploading an image using carrierwave in RoR. Whenever I try to upload a file I get this error:
You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed. If this is a file upload, please check that your upload form is multipart encoded.
users#edit:
= form_for(#user, multipart: true) do |f|
=f.file_field :avatar
= f.submit class: "btn btn-primary btn-block btn-lg"
users_controller:
def update
respond_to do |format|
if #user.update(user_params)
if params[:user][:avatar]
#user.avatar = params[:user][:avatar].tempfile.path
#user.save!
end
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
And I have mount_uploader :avatar, AvatarUploader in user.rb
Any ideas what could be going wrong?
You assign a string in avatar field in your controller so it was throwing error.
The controller code shoudl be
def update
respond_to do |format|
...
#user.avatar = params[:user][:avatar]
#user.save!
end
...
end
so it should be #user.avatar = params[:user][:avatar] not the file path which is string
I want to redirect_to slider_path after a user submits their email. Currently, only the success message is displayed without a redirect. Here's the code:
class Splash::SubscribersController < ApplicationController
def create
#subscriber = Subscriber.new(params[:subscriber])
if #subscriber.save
success = true
message = "Success! We'll let you know when we launch."
else
success = false
message = "Fail."
end
respond_to do |format|
format.html {
if success
flash[:success] = message
redirect_to slider_path
else
flash[:error] = message
end
redirect_to root_path
}
format.json { render :json => { :success => success, :message => message }.to_json }
end
end
end
Just replace this part of your code:
if success
flash[:success] = message
redirect_to slider_path
else
flash[:error] = message
end
redirect_to root_path
with this:
if success
flash[:success] = message
redirect_to slider_path
else
flash[:error] = message
redirect_to root_path
end
Rails API states:
An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:
def do_something
redirect_to :action => "elsewhere"
render :action => "overthere" # raises DoubleRenderError
end
If you need to redirect on the condition of something, then be sure to add “and return” to halt execution.
def do_something
redirect_to(:action => "elsewhere") and return if monkeys.nil?
render :action => "overthere" # won't be called if monkeys is nil
end
Note the use of and return
Neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
Add a return statement after your redirect. If the action also renders a template by default, any redirects need to be followed by a return statement.
if success
flash[:success] = message
redirect_to slider_path
return # <= Add a return.
else
flash[:error] = message
end
redirect_to root_path
I have ambethia's reCAPTCHA plugin on Rails 3 working. Does anyone know how to override it's flash message markup? I'd like to reuse my own flash_error div id instead of using the plugin's flash_recaptcha_error div id:
<div id="flash_recaptcha_error">incorrect-captcha-sol</div>
Also, how would you clean up this controller#create?
def create
#post = Post.new(params[:post])
respond_to do |format|
if verify_recaptcha(:model => #post, :error => "reCAPTCHA incorrect. Try again.") && #post.save
flash.now[:notice] = "Created \"#{#post.title}\""
format.html { redirect_to(#post, :notice => 'Post was successfully created.') }
else
flash.now[:error] = "Incorrect word verification. Are you sure you\'re human?"
format.html { redirect_to(:back, :error => 'reCAPTCHA incorrect. Try again.') }
end
end
end
Thanks for reading my question.
Because flash[] is an array you could delete element inside it. When we use recaptcha gem, the flash array contain recaptcha_error element, so you just only delete this element with :
flash.delete(:recaptcha_error) inside your controller.
For example :
if verify_recaptcha(:model=>#object,:message=>"Verification code is wrong", :attribute=>"verification code") && #object.save
#your code if succes
else
flash.delete(:recaptcha_error)
#your code if its fail
end
Maybe it could help you. Thanks
If you're making a User Authentication System from scratch, you may have to do something like this:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
respond_to do |format|
if verify_recaptcha(:model => #user )
if #user.save
format.html { redirect_to root_url, :notice => "You have Signed up!" }
else
format.html { render :new }
end
else
flash.delete(:recaptcha_error)
format.html { redirect_to( root_path , :flash => { :error => 'Please retry the two words of the reCaptcha' } ) }
end
end
end
end