I'm building a site where a link to fill a new form can be clicked from an Event show page
<%= link_to 'Be a Contestant', new_form_path(:event_id => #event.id)%>
This creates a link like
http://localhost:3000/forms/new?event_id=2
Now if the form is filled with an error, when submitted, it returns an error
Couldn't find Event with 'id'=""
So I decided to use the request.referrer to redirect back to the previous page but it doesn't list the errors as use this method
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to request.referrer }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
I also tried this but to no avail.
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to new_form_path(:event_id => request.referrer.params[:event_id]) }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
What you probably really need to do is to add a hidden field event_id to the form because I'm betting that event_id doesn't get propagated from the #new to the #create action.
See here for more information on hidden_field_tag
You usually just render the edit view when there was an error in create:
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { render :edit, alert: 'Error creating ...' }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
Related
I'm building an app like reddit where you add a Submission to a specific user page. Submission has a few attribute including an attribute called url.
I want to check when adding a new submission if already a submission with that same url exists for that specific page, and if it exist, vote for it instead of creating it as a new submission. If not, just add it as a new submission. I'm using the act_as_votable gem here.
Here is the create method:
def create
#user = User.friendly.find(params[:user_id])
#submission = #user.submissions.new(submission_params)
#submission.member_id = current_user.id
#submission.creator_id = #user.id
#submission.is_viewed = false
#submission.get_thumb_and_title_by_url(#submission.url)
respond_to do |format|
if #submission.save
format.html { redirect_to #user, notice: 'Submission was
successfully created.' }
format.json { render :show, status: :created, location: #submission }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
you should take a look at https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by and https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_initialize_by
Now on your code we can make changes like
def create
#user = User.friendly.find(params[:user_id])
#submission = #user.submissions.find_or_initialize_by(submission_params)
if #submission.id.present?
# What to do if the record exists
else
# if its a new record
#submission.member_id = current_user.id
#submission.creator_id = #user.id
#submission.is_viewed = false
#submission.get_thumb_and_title_by_url(#submission.url)
end
respond_to do |format|
if #submission.save
format.html { redirect_to #user, notice: 'Submission was
successfully created.' }
format.json { render :show, status: :created, location: #submission }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I hope that this can put you on the right track
Happy Coding
I have something strange in my rails app, I try to redirect the user to a specific page if a form is wrong formatted. It works but the URL does not match to the view.
I use files generated by rails g scaffold User. I added specific condition in model file to check user input to see if the form is well formatted or not and if not, it redirect him to the connection view.
I redirect him between 2 different controllers
So i turned this (app/controller/users_controller.rb):
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to root_path, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
into this:
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to root_path, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :template => 'pages/connection' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I tried and i'm well redirected to pages/connection.rb but the url in my browser is : http://url:8080/users and not http://url:8080/connection. So if i refresh, it leave pages/connection.rb to users/.
Also, error messages from model/user.rb aren't displayed.
what's wrong in my code ?
You are rendering the template pages/connection, you are not redirecting the user to the other controller.
format.html { render :template => 'pages/connection' }
Render and redirect are not the same
In my Calendar app both registered and unregistered users can create a meeting. In my meetings_controller :
def new
#meeting = Meeting.new
#meeting = current_user.meetings.new(meeting_params) if current_user
end
def create
respond_to do |format|
if #meeting.save
format.html { redirect_to #meeting, notice: 'Meeting was successfully created.' }
format.json { render :show, status: :created, location: #meeting }
else
format.html { render :new }
format.json { render json: #meeting.errors, status: :unprocessable_entity }
end
end
end
def meeting_params
params.require(:meeting).permit(:name, :start_time)
end
So, if a current_user exists it creates current_user.meetings.new(meeting_params) and if not, it should create just a Meeting.new without any user. However, it doesn't work and I get an error:
undefined method `save' for nil:NilClass
respond_to do |format|
if #meeting.save
format.html { redirect_to #meeting, notice: 'Meeting was successfully created.' }
format.json { render :show, status: :created, location: #meeting }
else
It works well if there is a current_user, but why the meeting without a user defines as 'nill' if I mentioned that it shout be just a Meeting_new? How can I make it work?
Thank you!
Change your controller code as like :
def new
#meeting = Meeting.new
end
def create
#meeting = Meeting.new(meeting_params) #edit
#meeting.user_id = current_user.id if current_user
respond_to do |format|
if #meeting.save
format.html { redirect_to #meeting, notice: 'Meeting was successfully created.' }
format.json { render :show, status: :created, location: #meeting }
else
format.html { render :new }
format.json { render json: #meeting.errors, status: :unprocessable_entity }
end
end
end
def meeting_params
params.require(:meeting).permit(:name, :start_time, :user_id)
end
I need to get the file name of and uploaded file in my controller so that i could set a default title (or name) to the uploaded file if the user did not assign one. I use Carrierwave to upload ing files.
My controller create action looks like this:
def create
#photo = Photo.new(params[:photo])
#photo.user_id = current_user.id
respond_to do |format|
if #photo.save
format.html { redirect_to #photo, notice: 'Photo was successfully created.' }
format.json { render action: 'show', status: :created, location: #photo }
else
format.html { render action: 'new' }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
The solution was to get the filename from the carrierwave file like this:
def create
#photo = Photo.new(params[:photo])
#photo.user_id = current_user.id
#photo.name = #photo.image.file.filename if #photo.name == ""
respond_to do |format|
if #photo.save
format.html { redirect_to #photo, notice: 'Photo was successfully created.' }
format.json { render action: 'show', status: :created, location: #photo }
else
format.html { render action: 'new' }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
I have the following create action:
def create
#report = Report.new(params[:report])
#file = params[:report][:data_file]
res = #report.get_report(#file, #report.year, #report.month)
file = open('report.pdf','wb')
file.write(res.body)
#report.file = file
respond_to do |format|
if #report.save
format.html { redirect_to #report, notice: 'Report was successfully created.' }
format.json { render json: #report, status: :created, location: #report }
else
format.html { render action: "new" }
format.json { render json: #report.errors, status: :unprocessable_entity }
end
end
end
However the HTTP response stored in the res variable can have a 200 code, or a 400 code that indicates a Bad Request. I want that if the res.code is 400, it also goes back to the new action with a warning message.
I tried including that condition on the respond_to if like below, but it didn't worked. It seems that after creating the instance it redirected to edit action. It makes no sense.
respond_to do |format|
if #report.save and res.code == 200
format.html { redirect_to #report, notice: 'Report was successfully created.' }
format.json { render json: #report, status: :created, location: #report }
else
format.html { render action: "new" }
format.json { render json: #report.errors, status: :unprocessable_entity }
end
end
What would be the correct way to do it?
It's a bit of a complicated workflow, but it looks like if res's status is 400, you just want to render the new form again. So you can early escape using the below:
if res.status != 200
render :new
return
end
respond_to do |format|
if #report.save
format.html { redirect_to #report, notice: 'Report was successfully created.' }
format.json { render json: #report, status: :created, location: #report }
else
format.html { render action: "new" }
format.json { render json: #report.errors, status: :unprocessable_entity }
end
end