When using activeadmin with rails 4, permit_params has to be set to allow fields to be saved.
simple fields are working, however a multi select for a has_many field is silently ignored. How can i set permit_params for that field?
so home has_many providers, and my admin looks like this:
ActiveAdmin.register Home do
permit_params :title, :intro, :providers, :providers_attributes => [:id]
menu :parent => "Content" , :label => "Home Page"
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs do
f.input :title
f.input :intro
f.input :providers
end
f.actions
end
index do
column :link
actions
end
end
I don't know if they changed it with Rails 4 .. but I've always done it this way
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs do
f.input :title
f.input :intro
end
f.has_many :providers do |pf|
pf.input :title #or whatever attributes you have there
pf.input :_destroy, :as => :boolean, :label => "Delete" if !pf.object.nil?
end
f.actions
end
And in your model.rb you should have something similar to
attr_accessible :providers_attributes
has_many :providers
accepts_nested_attributes_for :providers, :allow_destroy => true
Let me know if that helps !
Related
I have models products and gallery with has_many belongs_to relation, I'm implementing nested_attributes feature, Problem here is: When I click on add gallery two inner forms get created instead of one, as shown in below image:
CODE
form do |f|
f.inputs "Product" do
f.input :title, :required => true
f.input :description
f.input :price
f.input :display_image
f .input :product_detail, :hint => "Upload PDF file"
f.input :category
end
f.inputs 'Product Gallery' do
f.has_many :galleries, allow_destroy: true, new_record: 'Add Gallery' do |c|
c.input :image, :hint => c.template.image_tag(c.object.image.url(:thumb))
end
end
f.inputs 'Product Specification' do
f.has_many :specifications, allow_destroy: true, new_record: true do |c|
c.input :specification_label
c.input :specification_details
end
end
f.actions
end
I need help on this. I'm not able to solve this!!, any help would be appreciable.
Try this.
f.inputs 'Product Gallery' do
f.has_many :galleries do |c|
c.input :image, :hint => c.template.image_tag(c.object.image.url(:thumb))
c.input :_destroy, :as => :boolean
end
end
Hope this will work for you.
I have a Rails 4 app using Active Admin 1.0.0.pre1 in conjunction with pundit 0.3.0 for authorization which has worked flawlessly thus far, but I'm having trouble figuring out a good way automatically customize forms based on a user's role.
Given these models:
ActiveAdmin.register AdminUser do
permit_params do
Pundit.policy(current_admin_user, resource).permitted_attributes
end
form do |f|
f.inputs "Admin Details" do
f.input :role, as: :select, collection: [:manager, :admin]
f.input :email, as: :email
f.input :password
f.input :password_confirmation
end
f.actions
end
end
class AdminUserPolicy < ApplicationPolicy
def permitted_attributes
attributes = [:email, :password, :password_confirmation]
attributes += [:role] if user.has_role? :super_admin
attributes
end
end
I'd like for the role input to be automatically removed from the form.
One option would be something along the lines of:
permitted_attributes = Pundit.policy(current_admin_user, resource).permitted_attributes
form do |f|
f.inputs "Admin Details" do
f.input :role if permitted_attributes.include? :role
f.input :email
f.input :password
f.input :password_confirmation
end
f.actions
end
but, that approach requires the developer to remember which attributes should be checked, seems prone to forgetfulness and isn't exactly DRY. Perhaps, I am going about this the wrong way? All suggestions welcome.
Intercepting ActiveAdminForm by prepending a module that overrides input with a check against the Pundit policy seems to work well. Here is the implementation I went with:
# /lib/active_admin/permitted_active_admin_form.rb
module PermittedActiveAdminForm
def permitted_attributes
policy = Pundit.policy(current_admin_user, resource)
policy.respond_to?(:permitted_attributes) ? policy.permitted_attributes : []
end
def input(*args)
super(*args) if permitted_attributes.include? args[0]
end
end
# /config/initializers/active_admin.rb
module ActiveAdmin
module Views
class ActiveAdminForm < FormtasticProxy
prepend PermittedActiveAdminForm
end
end
end
# /app/admin/admin_user.rb
ActiveAdmin.register AdminUser do
permit_params do
resource ||= AdminUser
Pundit.policy(current_admin_user, resource).permitted_attributes
end
form do |f|
f.inputs "Admin Details" do
f.input :role, as: :select, collection: [:manager, :admin]
f.input :email, as: :email
f.input :password
f.input :password_confirmation
end
f.actions
end
end
Thanks to Andrey Deineko for starting me down the right path.
I know pundit, not active_admin. With that in mind, using the code you provided, I'll just throw an idea out there.
whitelist = Pundit.policy(current_admin_user, resource).permitted_attributes
fields = %i( role email password password_confirmation )
form do |f|
f.inputs "Admin Details" do
(fields & whitelist).each do |field|
f.input field
end
end
f.actions
end
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
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.
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