ActiveAdmin deleting attached CarrierWave images on form submission - ruby-on-rails-4

I'm not sure what I'm doing wrong here. File uploads are working but if I submit the form without selecting a file to upload it deletes the previously attached image(s).
Here's what the ActiveAdmin form looks like:
form do |f|
f.inputs do
f.input :model_number
f.input :description
f.input :slug
f.input :categories
f.has_many :product_images do |image|
image.input :product_id, as: :hidden, id: :product_id, input_html: { value: "%i" }
image.input :image
end
end
f.actions
end
And the relevant parts of the respective models:
class ProductImage < ActiveRecord::Base
belongs_to :product
mount_uploader :image, ProductImageUploader
validates :image, :product_id, presence: true
end
class Product < ActiveRecord::Base
has_many :product_images, dependent: :destroy
accepts_nested_attributes_for :product_images
validates_associated :product_images
end
Any insights would be much appreciated. Thanks!

It looks like I was a bit overzealous with my validations. Removing product id from the ProductImages validations and simplifying image.input :product_id, as: :hidden, id: :product_id, input_html: { value: "%i" } in the form to image.input :product_id, as: :hidden in the form makes image attach correctly to existing products or new products.

Related

Rails 4 nested fields_for not saving

I see many posts, but I am not sure they apply to my problem. Mainly because when I try to implement those solutions I get syntax errors. I don't know why this seems to be such a problem.
I have profile object that has a 1:1 relationship with user. In the edit of profile I want to save the email of user. But it will not save here is the code and output...
View:
= semantic_form_for #profile do |f|
= f.inputs class: "form-group" do
= f.input :name, input_html: { class: "form-control" }
= f.input :username, input_html: { class: "form-control" }
= f.semantic_fields_for #profile.user do |u|
= u.input :email, input_html: { class: "form-control" }
The paramaters being passed to the controller:
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"iMkkLX6qN7PagmbnEQlQZ0CH5Q/fl+G9273eHFO9aRk8EG4MisEi3PwQOWocU2wp3UW5ju4DOJcUh5v19pS46A==", "profile"=>{"name"=>"John Doe", "username"=>"JohnnyD", "user"=>{"email"=>"jdoe#email.com"}, "commit"=>"Save", "controller"=>"profiles", "action"=>"update", "id"=>"4"}
The response from the controller:
Unpermitted parameter: user
The whitelisting:
params.require(:profile).permit(:name, :username, :user)
The models:
class Profile < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user
end
class User < ActiveRecord::Base
has_one :profile, :dependent => :destroy
end
I have tried adding users_attributes: [:email] to the required params #syntax error.
I have tried adding user: [:email] to the required prarams #syntax error
I have tried with and without accepts_nested_attributes in the model #no effect.
Can someone clue me in, because I am clearly clueless.
Thanks.
I see two problems:
First - = f.semantic_fields_for #profile.user do |u| Should be:
= f.semantic_fields_for users do |u|
(Here you are telling Rails to pick related Database table, so should be plural users)
And second - strong params should really be as you already tried:
params.require(:profile).permit(:name, :username, users_attributes: [:email])
Hope it fixes your issue.

Rails nested_form Invalid association. Make sure that accepts_nested_attributes_for is used for assoctiation

I am using rails 4.0.4 with nested_form 0.3.2 to build an app that allows users to organize movies in lists.
I have these main models, a List model (I've excluded things such as validations):
class List < ActiveRecord::Base
belongs_to :user
has_many :list_movie_pairs
has_many :movies, :through => :list_movie_pairs
accepts_nested_attributes_for :list_movie_pairs, :allow_destroy => true
accepts_nested_attributes_for :movies, :allow_destroy => true
end
A Movie model:
class Movie < ActiveRecord::Base
has_many :list_movie_pairs
has_many :lists, :through => :list_movie_pairs
has_many :reviews
end
A ListMoviePair model for the many-to-many relationship:
class ListMoviePair < ActiveRecord::Base
belongs_to :list
belongs_to :movie
validates_presence_of :list_id, :movie_id
validates_uniqueness_of :movie_id, scope: :list_id
end
I am trying to build an interface for the user to add movies to a created list. These routes serve my purpose:
get "/users/:username/lists/:id/add" => "lists#add_movies", :as => :user_list_list_movie_pairs
post "/users/:username/lists/:id/add" => "lists#submit_movies"
These are the classes in my ListsController that should make this possible:
def add_movies
#pair = list.list_movie_pairs.new # "list" is a helper that returns the current list
end
def submit_movies
#list = current_user.lists.find(params[:id])
#pair = #list.list_movie_pairs.new(pair_params)
if #pair.save
redirect_to user_list_path(current_user.username, #list)
else
render :add_movies
end
end
def list_params
params.require(:list).permit(:name, :description, :private, \
list_movie_pairs_attributes: [:id, :list_id, :movie_id, :_destroy], \
movies_attributes: [:id, :title, :_destroy])
end
And this is the form in my view
<%= nested_form_for [current_user, list, #pair] do |f| %>
<%= f.fields_for :movies do |movie_form| %>
<%= movie_form.text_field :title %>
<%= movie_form.link_to_remove "Remove movie" %>
<% end %>
<%= f.link_to_add "Add movie", :movies %>
<% end %>
I get this error when trying to access the view:
Invalid association. Make sure that accepts_nested_attributes_for is used for :movies association.
Which pops at this line:
<%= f.link_to_add "Add movie", :movies %>
Note 1: I am using the Devise gem for users, hence the "current_user" helper;
Note 2: I have tried using both "movies" and "list_movie_pairs", i.e.:
f.fields for :list_movie_pairs
and
f.link_to_add "Add movie", :list_movie_pairs
in my view, neither association seems to work
Your code in the view should be like this
<%= nested_form_for [current_user, list, #pair] do |f| %>
<%= f.fields_for :movies do |movie_form| %>
<%= movie_form.text_field :title %>
<%= movie_form.link_to_remove "Remove movie" %>
<%= movie_form.link_to_add "Add movie", :movies %> #note the change here
<% end %>
<% end %>
Update
There are several issues in your code
1.In your List model,this line is not required
accepts_nested_attributes_for :movies, :allow_destroy => true #not requied
2.In your ListsController,you have this line
#pair = #list.list_movie_pairs.new(pair_params)
It should be
#pair = #list.list_movie_pairs.new(list_params) because you have list_params method not pair_params

activeadmin carrierwave image hint not displayed

HI I am using active admin with carrier gem. I am unable to view preview on image upload in hint
my image src is always empty i.e f.template.image_tag(f.object.image.url) is empty
I can see image relative url after clicking upload button.
my form looks like this
ActiveAdmin.register Product do
permit_params :name, :description , :category_id , :image
form(:html => { :multipart => true }) do |f|
f.inputs "Product" do
f.input :category_id , :as => :select , :collection => Category.all
f.input :name
f.input :description
f.input :image, :as => :file, :hint => f.template.image_tag(f.object.image.url)
end
f.actions
end
end
model
class Product < ActiveRecord::Base
belongs_to :category
mount_uploader :image, ImageUploader
end
serializer
class ProductSerializer < ActiveModel::Serializer
attributes :id, :name, :description , :image
end
my uploader looks like this
class ImageUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
GENERATE HTML
<label class="label" for="product_image">Image</label>
<input id="product_image" name="product[image]" type="file">
<p class="inline-hints"><img src=""></p>
After a few modifications, for me works fine:
ActiveAdmin.register Team do
permit_params :name, :country :image
index do
selectable_column
column :nome
column :country
actions
end
form do |f|
f.inputs "Team" do
f.input :nome
f.input :country
f.input :image, :image_preview => true
end
f.actions
end
show do
attributes_table do
row :nome
row :country
row :image do
image_tag(equipe.image.url)
end
end
end
end
You can see that I use three options:
- Index: to show the list of items
- Form: for the form
- Show: to show the item details
This way you can customize all pages.

Rails4 Simple_form nested form field not displaying

I am a newbie to Ruby on Rails and have scoured Stackoverflow and the internet to the best of my abilities and am still stumped.
In my set-up, a Rating belongs_to a Product and has_many Comments. I'm using simple-form and trying to use nested fields_for to add RatingComment through the Rating form. Interestingly, when using the singular form of :rating_comment, the field is displayed. But as expected, I get the unpermitted parameter error when trying to save. When I use plural :rating_comments, the field disappears. This is similar to this SO posting, but adding #rating.rating_comments.build to new action still does not work for me. I've tried restarting the server many times, and even reset the database to no avail. Would appreciate any assistance as I've been struggling with this issue for the past few days.
Note: I've also taken out what I think is irrelevant code from the snippets below. If I need to show more information, please do let me know. Thanks in advance!
routes.rb
resources :ratings, only: [:new, :create, :edit, :update, :destroy] do
resources :rating_comments, shallow: true
end
rating.rb
class Rating < ActiveRecord::Base
belongs_to :product
belongs_to :user
has_many :rating_comments, foreign_key: "rating_id", dependent: :destroy
accepts_nested_attributes_for :rating_comments, reject_if: :all_blank
end
rating_comment.rb
class RatingComment < ActiveRecord::Base
belongs_to :rating
validates :rating_id, presence: true
end
ratings_controller.rb
class RatingsController < ApplicationController
before_action :signed_in_user, only: [:create, :new, :show]
def new
#product = Product.find(params[:id])
#rating = #product.ratings.new
#rating.rating_comments.build
end
def create
#product = Product.find(params[:product_id])
#rating = #product.ratings.build(rating_params)
#rating.user_id = current_user.id
...
private
def rating_params
params.require(:rating).permit(:user_id, :product_id, :rating, rating_comments_attributes: [:rating_id, :content])
end
end
ratings/_new_rating_form.html.erb
<%= simple_form_for([#product, #rating], html: { class: 'form-horizontal' }) do |f| %>
<%= f.error_notification %>
<%= f.input :rating, collection: 1..10, as: :radio_buttons,
item_wrapper_class: 'inline', checked: 5 %>
<%= f.simple_fields_for :rating_comments do |rc| %>
<fieldset>
<%= rc.input :content, label: "Comments" %>
</fieldset>
<% end %>
<%= f.error :base %>
<%= f.button :submit, "Submit" %>
<% end %>
Very embarrassed to admit that it turns out that I had the view written in the wrong action. Once I put it in the new.html, it finally worked.

Activeadmin has_many form for show and edit only

First please note that i am working with rails 4 and activeadmin rails 4 branch. https://github.com/gregbell/active_admin/tree/rails4
I have two models pictue which is ploymorphic
class Picture < ActiveRecord::Base
belongs_to :picture_category
belongs_to :imageable, polymorphic: true
mount_uploader :image, ImageUploader
end
And ship
class Ship < ActiveRecord::Base
has_many :pictures, as: :imageable
accepts_nested_attributes_for :pictures
end
And activeadmin ship.rb
ActiveAdmin.register Ship do
form do |f|
f.inputs do
f.inputs
f.has_many :pictures, :sortable => :picture_categories do |ff|
ff.input :name
end
end
f.actions
end
controller do
def permitted_params
params.permit(:ship => [:name, :title, :short_desc, :description, :position, :pictures, :enabled, :ship_provider_id, :picture_category_id, :picture_id])
end
end
end
but the result is this:
How can get rid of delete button and have submit
how can i show this form only on show and edit form because thats not make sense having child before parents
Please point what are mistakes in code.
I know how make a solve a first problem/
You need insert :submit action instead button for your nested resource input. Example:
form do |ship|
ship.inputs t(:ship_details) do
ship.input :name, :label => t(:name)
ship.input :description, :label => t(:description)
ship.has_many :pictures do |picture|
picture.input :url
picture.input :imgdescription
picture.actions do
picture.action :submit
end
end
end
end