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
Related
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.
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
Good day!
I'm trying to implement ajax in my rails test app.
my controller code app/controllers/admin/data
class Admin::DataController < ApplicationController
...
def ajax
if params[:ajax] == 'list'
#responce = Admin::Datum.all
else
#responce ={error: true}
end
respond_to do |format|
# format.html { redirect_to #user }
# format.js
format.json { render json: #responce }
end
end
end
index.js.erb
alert('1');
$.post('/admin/data/ajax',{ajax:'list'},function(responce){
alert('2');
console.log(responce);
}
);
could you help me in determining the url that i've to use in ajax to access ajax method?
or any other help is very welcome!
Update 1
Updated initial code to represent more complex problem
I added to routes.rb
match 'admin/data/ajax' => 'Admin::Data#ajax'
could be any url, it's what you write in your jquery.
And it works!
I have the follow models:
User
has_many :armies
Army
belongs_to :user
My controller with the added current_user:
class ArmiesController < ApplicationController
before_filter :authenticate_user!
def new
#army = Army.new
end
def create
#army = current_user.armies.new(params[:army])
respond_to do |format|
if #army.save
format.html { redirect_to new_army_path, :notice => "New army added" }
else
format.html { render :new }
end
end
end
end
I want to use my last created forms value for the new one. We'll use my strength field as an example:
<%= form_for #army do |f| %>
<%= f.label :strength, "Army Strength" %>
<%= f.text_field :amount %>
<%= f.submit "Create" %>
<% end %>
How can I save the value that the user input's in the strength field so it remains on the form after the last form is created?
EDIT:
def new
#army = Army.new(strength: session[:last_army_strength],
type_id: session[:last_type])
end
def create
#army = current_user.armies.new(params[:army])
session[:last_army_strength] = params[:army][:strength]
session[:last_type] = params[:army][:type_id]
respond_to do |format|
if #army.save
format.html { redirect_to new_army_path, :notice => "New army added" }
else
format.html { render :new }
end
end
end
end
I think this should work:
class ArmiesController < ApplicationController
before_filter :authenticate_user!
def new
#army = Army.new(strength: session[:last_army_strength])
end
def create
#army = current_user.armies.new(params[:army])
session[:last_army_strength] = params[:army][:strength]
respond_to do |format|
if #army.save
format.html { redirect_to new_army_path, :notice => "New army added" }
else
format.html { render :new }
end
end
end
end
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.