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
Related
I'm new to rails. Im developing an app which contains adding customers.In that I have download button.When I click download button It should download the current customer page in csv file.
Controller
def create
#customer_detail = CustomerDetail.new(customer_detail_params)
#customer_detail.company_profile_id = current_user.company_profile.id
respond_to do |format|
if #customer_detail.save
format.html { redirect_to edit_customer_detail_path(#customer_detail), notice: 'customerDetails was successfully created.' }
# format.html { render 'edit', notice: 'customerDetails was successfully created.' }
else
format.html { render :new }
end
end
end
def index
#customer_details = CustomerDetail.all
end
def destroy
end
def update
respond_to do |format|
format.html
format.csv { render text: #customer_details.to_csv }
if #customer_detail.update(customer_detail_params)
format.html { redirect_to #customer_detail, notice: 'customer_details was successfully updated.' }
else
format.html { render :edit }
end
end
end
View
.fieldset
.row
.col-sm-3
= f.submit "Save", class: "btn btn-primary"
.col-sm-3
= f.submit "cancel", type: :reset, class: "btn btn-primary"
.col-sm-3
= link_to "Download", edit_customer_detail(format: "csv"), class: "btn btn-primary"
.col-sm-3
= link_to("Print", "javascript:print()", class: "btn btn-primary")
The problem is it downloads all the records from of the form. I dont know whether to action is to be given in update or edit.If i give the path edit_customer_detail instead of customer_details_(path) it shows template error and no route matches error when clicking download button.can someone please help me.I've attached the output link here. thanks in advance!!
Customer_details.csv
In controller's update method, change below line:
format.csv { render text: #customer_details.to_csv } with
format.csv { render text: #customer_detail.to_csv }
In application.rb
add require 'csv'
Change your update function to
def update
respond_to do |format|
format.html
format.csv { render text: #customer_detail.to_csv }
if #customer_detail.update(customer_detail_params)
format.html { redirect_to #customer_detail, notice: 'customer_details was successfully updated.' }
else
format.html { render :edit }
end
end
You were downloading report for all users because #customer_details = CustomerDetail.all returns data for all users.
model
def to_csv
CSV.generate do |csv|
csv << self.class.column_names
csv << self.attributes.values_at(*self.class.column_names)
end
end
controller
def download_csv
respond_to do |format|
format.html
format.csv { render text: #customer_detail.to_csv }
end
end
view
.col-sm-3
- if #customer_detail.save
= link_to "Download", download_csv_customer_detail_path(#customer_detail.id, format: "csv"), class: "btn btn-primary"
I've added seperate method of action in controller and changed method and routes.finally got an answer
I want to create a new record if it not exist. Otherwise, redirect to edit page automatically.
In case the record exists (e.g: #sale is not nil). However, I got error message:
app/views/sales/_form.html.erb where line #1 raised:
First argument in form cannot contain nil or be empty
Please show place where I had mistake.
sales_controller.rb
def new
#sale = Sale.find_on_today
if #sale.nil?
#sale = Sale.new
else
redirect_to edit_sale_path(#sale)
end
end
def edit
end
# POST /sales
def create
Kpi.transaction do
#sale = Sale.new(sale_params)
#sale.user_id = current_user.id
respond_to do |format|
if #sale.save
format.html { redirect_to sales_path, notice: 'Sale was successfully created.' }
else
format.html { render :new }
end
end
end
end
# PATCH/PUT /sales/1
def update
respond_to do |format|
if #sale.update(sale_params)
format.html { redirect_to sales_path, notice: 'Sale was successfully updated.' }
else
format.html { render :edit }
end
end
end
private
def sale_params
params.require(:sale).permit(:sale_money, :no_of_items)
end
_form.html.erb
<%= form_for #sale do |f| %>
<label for="sale_money"><%= t('.sale_money_label')%></label>
<%= f.text_field :sale_money, class: "form-control" %>
<label for="no_of_items"><%= t('.no_of_items_label')%></label>
<%= f.text_field :sale_amount, class: "form-control" %>
<%= f.submit t('.btn_submit'), class: 'btn btn-primary' %>
<% end %>
UPDATE: Based on fylooi's answer, I forget redirect is a new request, so #sale is nil. I change method new, edit and update in controller, it is working
sales_controller.rb
def new
#sale = Sale.find_on_today
if #sale.nil?
#sale = Sale.new
else
redirect_to edit_sale_path(#sale.id)
end
end
def edit
#sale = Sale.find(params[:id])
end
def update
#sale = Sale.find(params[:id])
respond_to do |format|
if #sale.update(kpi_params)
format.html { redirect_to kpis_path, notice: 'Sale was successfully updated.' }
else
format.html { render :edit }
end
end
end
edit.html.erb
<%= render partial: 'form' %>
A redirect is a fresh request to Rails. You need to set #sale again in the edit action as it is not persisted from update.
Alternatively, you can render the edit view directly from update if the update fails. That will preserve the instance variables from update.
I made model Role with rolify gem.
But controller made to namespace :admin :
class Admin::RolesController < ApplicationController
def index
#roles = Role.all
end
def new
#role = Role.new
end
def create
#role = Role.new(role_params)
respond_to do |format|
if #role.save
format.html { redirect_to admin_role_path(#role), notice: 'Роль создана.' }
format.json { render action: 'show', status: :created, location: #role }
else
format.html { render action: 'new' }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
def show
#role = Role.find(params[:id])
end
def edit
#role = Role.find(params[:id])
end
def update
respond_to do |format|
if #role.update(role_params)
format.html { redirect_to admin_role_path(#role), notice: 'Роль обновлена.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
def destroy
#role = Role.find(params[:id])
#role.destroy
respond_to do |format|
format.html { redirect_to admin_roles_url }
format.json { head :no_content }
end
end
private
def set_role
#role = Role.find(params[:id])
end
def role_params
params.require(:role).permit(:name)
end
end
When I want to update Role, I open form, edit, click submit and get error:
Routing Error
No route matches [PATCH] "/admin/roles.4"
Please help me.
Based on the form code you pasted above, you'll see that url is pointing to the path used for creates but not updates.
You should be able to update your call to simple_form like so:
= simple_form_for [:admin, #role], :html => { :class => 'form-horizontal' } do |f|
You'll see that you can pass an array with symbolized namespace names and the object instance, and it'll build the URL correctly for both POSTs and PATCHes.
Problem is solved.
In _form I fix url.
= simple_form_for #role, url: admin_role_path(#role), :html => { :class => 'form-horizontal' } do |f|
Hi I'm trying to use a form as a partial for both the new/edit views of my albums controller/model. However, it's giving me the error when I try to edit the album:
No route matches [PUT] "/users/22/albums"
I think this might have to do with my form's :url. My form works fine when I submit it to create an album, but gets that error when I try to edit it.
I tried taking out the url: user_albums_path in my form, but it would just give me an error when I try to create a new album.
No route matches [POST] "/albums"
Is there any way to make it so that the form works for both actions? I feel like the :url can't coexist properly in both actions.
_form.html.erb
<%= form_for (#album), url: user_albums_path, :html => { :id => "uploadform", :multipart => true } do |f| %>
<div class="formholder">
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :description %>
<%= f.text_area :description %>
<br>
<%=f.submit %>
</div>
<% end %>
albums controller
class AlbumsController < ApplicationController
def index
#user = User.find(params[:user_id])
#albums = #user.albums.all
respond_to do |format|
format.html
format.json { render json: #albums }
end
end
def show
#user = User.find(params[:user_id])
#album = #user.albums.find(params[:id])
end
def update
#user = User.find(params[:user_id])
#album = #user.albums.find(params[:id])
respond_to do |format|
if #album.update_attributes(params[:album])
format.html { redirect_to user_album_path(#user, #album), notice: 'Album successfully updated' }
else
format.html { render 'edit' }
end
end
end
def edit
#user = User.find(params[:user_id])
#album = #user.albums.find(params[:id])
end
def create
#user = User.find(params[:user_id])
#album = #user.albums.build(params[:album])
respond_to do |format|
if #user.save
format.html { redirect_to user_album_path(#user, #album), notice: 'Album was successfully created.' }
format.json { render json: #album, status: :created, location: #album}
else
format.html { render action: "new" }
format.json { render json: #album.errors, status: :unprocessable_entity }
end
end
end
def new
#user = User.find(params[:user_id])
#album = Album.new
end
def destroy
end
end
please help!
update:
FIXED IT! on my own! the form just needed to be <%= form_for([#user, #album])...
Try
<%= form_for [#user, #album] %>
# other arguments can be inserted before the closing brace
That syntax properly scopes the resource routes
Remember to have an #album instance variable if you need one. You can build an empty album using #user.album.build
I'm trying to pass a project id from a session in a hidden field on a task form, so that when the task is created, it has the id of the project that it is assigned to. I've done this before fine, and have even tried copying over the code that I used from when it worked, but changing names and I'm getting errors no matter what I do - if anyone could help point out where I'm going wrong, it would be much appreciated, thanks!
The error I'm getting with this configuration is: "unknown attribute: project_id"
View Code (tasks/_form):
<%= form_for(#task) do |f| %>
<div class="field">
<%= f.hidden_field :project_id, :value => session[:project_id] %>
</div>
...
<% end %>
Model Code (task):
attr_accessible :project_id
belongs_to :project
Controller code (tasks_controller):
def new
#task = Task.new
#project_id = session[:project_id]
respond_to do |format|
format.html # new.html.erb
format.json { render json: #task }
end
end
def create
project_id = session[:project_id]
#task = Task.new(params[:task])
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render json: #task, status: :created, location: #task }
else
format.html { render action: "new" }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
Here's the application trace - it is pointing to line 46, which in my code is the '#task = Task.new(params[:task])' line in the create action...?
app/controllers/tasks_controller.rb:46:in `new'
app/controllers/tasks_controller.rb:46:in `create'
Does the Task model have a project_id column?