In Active Admin I want to add image upload on an association on a model inside a nested form, using the method shown here. The code doesn't cause any error, but when I load the form, the file upload section (the part using inputs inside the has_many), doesn't show up at all. Code looks something like this:
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs “My Model” do
f.has_many :model_associations do |ma|
ma.inputs “Image Upload” do |image|
image.input :file, as: :file
end
end
end
end
I wonder if the problem is that I have an inputs inside the has_many? Should I be able to have an inputs inside a has_many?
I think that you don't need this line at all:
ma.inputs 'Image Upload' do |image|
Just rewrite it like so:
form do |f|
f.semantic_errors(*f.object.errors.keys)
f.inputs 'My Model' do
f.has_many :model_associations do |i|
i.input :file, as: :file
end
end
f.actions
end
Related
A typical form produced by the ActiveAdmin DSL might look like so:
ActiveAdmin.register Post do
...
form do |f|
f.inputs do
f.input :title
f.input :content
end
f.actions
end
...
end
The f.actions bit renders both a submit button and a cancel link. The problem is that the latter's target is always the index page. Instead, for a previously persisted record I would like to be taken back to the show page. As a possible workaround, f.actions could be replaced with:
f.actions do
f.action :submit
if resource.persisted?
f.cancel_link({action: :show})
else
f.cancel_link
end
end
This, however, seems verbose and clunky. Am I missing some more idiomatic trick to accomplish the same?
I'm trying to get file uploading to work with a nested fields_for tag in a Rails 4 app. I've followed several Railscasts, namely: 253, 381, 383, but still can't quite get it fully functioning. Also using Carrierwave & jquery file upload.
Basic app structure is as follows:
blogpost.rb
class Blogpost < ActiveRecord::Base
has_many :blogpics
end
blogpic.rb
class Blogpic < ActiveRecord::Base
belongs_to :blogpost
end
blogposts_controller.rb
def new
#blogpost = Blogpost.new
blogpic = #blogpost.blogpics.build
end
blogpost_form.html.erb
<div>
<%= form_for #blogpost do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.hidden_field :post_id %>
<%= f.text_field :title %>
<%= f.text_field :location %>
<%= f.text_area :content %>
<%= f.fields_for :blogpics do |builder| %>
<%= builder.file_field :image %>
<%= builder.hidden_field :blogpost_id %>
<% end %>
<p><%= f.submit %></p>
<% end %>
Uploading a single file works. But, adding ":multiple => true, :name => 'blogpic[image]'" to the file field breaks functionality and no files upload.
When I edit blogposts_controller.rb as such:
def new
#blogpost = Blogpost.new
3.times do
blogpic = #blogpost.blogpics.build
end
end
I am able to input three files individually, then upload successfully. Is there any way I can achieve this functionality while being able to drag & drop multiple files into one input?
I really appreciate any help and direction, thanks.
Your blogpost model is missing an accepts_nested_attributes association.
class Blogpost < ActiveRecord::Base
has_many :blogpics
accepts_nested_attributes_for :blogpics
end
I'm not quite sure how handling multiple files in one dialog box. I'd imagine you'd be using some javascript to detect that multiple files were selected, and creating field forms for each of them.
You can pass :multiple => true as a param on builder.file_field :image. See http://apidock.com/rails/ActionView/Helpers/FormTagHelper/file_field_tag for details
With the multiple attribute on the file input, you can drag and drop ONTO the input element
See for details http://www.html5rocks.com/en/tutorials/file/dndfiles/#toc-selecting-files
I've run into the same issue (where multiple: true breaks the nested form) and my understanding is that you have to manually transform the params before the controller receives it. If you inspect (using pry or debugger) the params hash, you need to compare between submitting Parent Model with several input files (on individual inputs) VERSUS Parent Model with multiple input files (in one input). The former creates an array of child objects (each with their own file), while the latter creates only one child object that has all the images in one array.
I'm trying to add a form to the show page of a resource. The form works just fine, but it will only show up if I wrap it in a panel declaration, which results in a panel-within-a-panel.
Any idea how to get the form to show up without wrapping it in a panel?
Here's the code I have right now:
show do |ad|
...
panel "Foobar" do
semantic_form_for [:admin, resource, resource.reactions.build], builder: ActiveAdmin::FormBuilder do |f|
f.inputs "New Reaction" do
f.input :title
f.input :content
end
f.actions
end
end
end
Thanks!
An alternative to the panel would be to use a div.
The root issue is mixing Arbre and non-Arbre components; here those components are panel and the semantic_form_for. This alteration works because the last return value in an Arbre block is wrapped in a text_node when it is a String. In this case, the form is output as a string and then is wrapped as a text_node within the div, which renders the form. See Arbre's Element source for more info.
show do |ad|
div do # <- Note the div
semantic_form_for [:admin, resource, resource.reactions.build], builder: ActiveAdmin::FormBuilder do |f|
f.inputs "New Reaction" do
f.input :title
f.input :content
end
f.actions
end
end
end
I have an existing form which is tied to a model named 'Order', but i want to add new form fields that will capture Credit Card info such as name, cc number, etc to be processed on a 3rd party payment gateway.
But since i don't want to save CC info in our database, there are no corresponding columns of that in my order table. And this gives me an error when submitting the form that those Credit card input fields are not 'part' of the order model.
If I understand your answer correctly, what you want to do is explained in the official wiki page here: Create a fake input that does NOT read attributes. You can use a field not related to any real database column by Edward's suggestion, however you don't need to define an attribute in your model if the form field is nothing to do with the model.
In summary, the trick explained in the page is defining a custom input called 'FakeInput' and use it like this:
<%= simple_form_for #user do |f| %>
<%= f.input :agreement, as: :fake %>
....
Do not forget to restart your rails server after adding/modifying a custom input as Fitter Man commented.
UPDATE: Please note that the official wiki page has updated and the sample code on the wiki page is not working for those which use older versions of SimpleForm. Use code below instead if you encounter an error like undefined method merge_wrapper_options for.... I'm using 3.0.1 and this code works well.
class FakeInput < SimpleForm::Inputs::StringInput
# This method only create a basic input without reading any value from object
def input
template.text_field_tag(attribute_name, input_options.delete(:value), input_html_options)
end
end
You can use attr_accessor
class Order < ActiveRecord::Base
attr_accessor :card_number
end
Now you can do Order.first.card_number = '54421542122' or use it in your form or whatever else you need to do.
See here for ruby docs http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-attr_accessor
and here for a useful stackoverflow question What is attr_accessor in Ruby?
Don't get it mixed up with attr_accessible! Difference between attr_accessor and attr_accessible
The best way to handle this is to use simple_fields_for like so:
<%= simple_form_for #user do |f| %>
<%= f.input :first_name %>
<%= f.input :last_name %>
<%= f.input :email %>
<%= simple_fields_for :other do |o| %>
<%= o.input :change_password, as: :boolean, label: 'I want to change my password' %>
<% end %>
<% end %>
In this example, I have added a new field called change_password which is not part of the underlying user model.
The reason this is a good approach, is that it lets you use any of the simple form inputs / wrappers as fields. I don't care for the answer by #baxang, because it doesn't allow you to use different types of inputs. This seems more flexible.
Notice though for this to work, I had to pass :other to simple_fields_for. You can pass any string/symbol as long as there is not a model with that same name.
I.e. unfortunately I can't pass :user, as simple_form would try to instantiate a User model, and we'd get the same error message again...
Also if you're just trying to add something and get it into the params, but leaving it out of the model's hash, you could just do FormTagHelpers. http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html
Example:
<%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
<%= devise_error_messages! %>
<% resource.class.invite_key_fields.each do |field| -%>
<%= f.input field %>
<%= hidden_field_tag :object_name, #object.class.name %>
<%= hidden_field_tag :object_id, #object.id %>
<% end -%>
I found a very simple (and somewhat strange) workaround.
Just add the input_html option with any value key inside. E.g:
= simple_form_for #user do |f|
= f.input :whatever, input_html: {value: ''}
Tested simple_from versions: 3.2.1, 3.5.1
I'm putting up the same question I asked here in activeadmin's issues board on github:
https://github.com/gregbell/active_admin/issues/645
Hi,
I have two different issues.
1: i love the way active admin handles has_many relationships with a simple DSL like so:
ActiveAdmin.register Artist do
form do |f|
f.inputs do
f.input :name
f.input :description
end
f.inputs "ArtistLinks" do
f.has_many :artist_links do |j|
j.inputs :title, :url
end
end
f.buttons
end
end
The ability to add more links at the bottom of the form is great.
However,I have been using a wyiswyg which i can't seem to get working in this format. I've been using/adding it with a partial like so:
ActiveAdmin.register NewsItem do
form :partial => "/news_items/form"
end
/app/views/news_item/_form.html.erb
<%= javascript_include_tag "/javascripts/ckeditor/ckeditor.js" %>
<%= semantic_form_for [:admin, #news_item], :multipart => true do |f| %>
<%= f.inputs :title, :photo, :excerpt %>
<%= cktext_area_tag("news_item[content]", #news_item.content) %>
<%= f.submit %>
<% end %>
However,
in my partial, i can't seem to be able to make the has_many relationship nicely like so:
f.inputs "ArtistLinks" do
f.has_many :artist_links do |j|
j.inputs :title, :url
end
end
Could you either explain to me how to get my wysiwyg which uses a form helper cktext_area_tag into my admin resource or explain to me how to get that nice has_many into my view partial?
Thanks a bunch!
The reason why has_many does not work in partials is because Active Admin tells you to use semantic_form_for when writing your partial. Active Admin extends Formtastic which it uses to generate forms. It does so by creating its own form builder that extends the Formtastic builder and adds, among others, the has_many method. So if you want to use that inside partials you have to use the Active Admin form builder. To do that use active_admin_form_for instead of semantic_form_for.
If you have problems using active_admin_form_for, take a look at my branch which should fix most of the issues (it's still beta - but I'm working on getting it into Active Admin core)