Get file name of Carrierwave upload in rails controller - ruby-on-rails

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

Related

change behaviour of Create if record with same attribute exists

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

How can I allow to create a new object both for registered and unregistered users?

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

Passing an argument on request.referrer

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

Getting ID from an item that's not saved yet

I am saving data to two different models at once. This has successfully been done.
These two models are associated with each other, so one most store the others ID on save. How to I store the questionnaire_contact_id in QuestionnaireResult?
class QuestionnaireResultsController < ApplicationController
def create
#questionnaire_result = QuestionnaireResult.new(params[:questionnaire_result])
#questionnaire_contact = QuestionnaireContact.new(params[:questionnaire_contact])
respond_to do |format|
if #questionnaire_result.save
#questionnaire_contact.save
format.html { redirect_to root_path, notice: 'Questionnaire was successfully submited.' }
format.json { render json: questionnaires_path, status: :created, location: questionnaires_path }
else
format.html { render action: "new" }
format.json { render json: questionnaires_path.errors, status: :unprocessable_entity }
end
end
end
end
You should use activerecord associations:
def create
#questionnaire_result = QuestionnaireResult.new(params[:questionnaire_result])
#questionnaire_contact = #questionnaire_result.questionnaire_contacts.new(params[:questionnaire_contact])
respond_to do |format|
if #questionnaire_result.save #this line will automatically save associated contact
# code
else
# code
end
end
end
Solved, it was as easy as doing this:
class QuestionnaireResultsController < ApplicationController
def create
#questionnaire_result = QuestionnaireResult.new(params[:questionnaire_result])
#questionnaire_contact = QuestionnaireContact.new(params[:questionnaire_contact])
respond_to do |format|
#questionnaire_contact.save
#questionnaire_result.admin_questionnaire_contact_id = #questionnaire_contact.id
if #questionnaire_result.save
format.html { redirect_to root_path, notice: 'Questionnaire was successfully submited.' }
format.json { render json: questionnaires_path, status: :created, location: questionnaires_path }
else
format.html { render action: "new" }
format.json { render json: questionnaires_path.errors, status: :unprocessable_entity }
end
end
end
end

Change action respond_to depending on response code

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

Resources