ActiveAdmin nested form doesn't work - ruby-on-rails

I am using ActiveAdmin in my rails application.My setup is the following:
app/models/translation_type.rb
class TranslationType < ActiveRecord::Base
has_many :translation_details
accepts_nested_attributes_for :translation_details, allow_destroy: true
end
app/models/translation_detail.rb
class TranslationDetail < ActiveRecord::Base
belongs_to :translation_type
attr_accessor :id, :language_from, :language_to, :price
end
app/admin/translation_type.rb
ActiveAdmin.register TranslationType do
permit_params :translation_type, translation_details_attributes: [:id, :language_from, :language_to, :price, :_destroy]
index do
column :translation_type
column :translation_details
column :created_at
column :updated_at
actions
end
filter :translation_type
filter :created_at
form do |f|
f.inputs "Translation Type Details" do
f.input :translation_type
f.input :created_at
f.input :updated_at
end
f.inputs do
f.has_many :translation_details, allow_destroy: true do |tran_det|
tran_det.input :language_from, :collection => ['Gr', 'En', 'Fr', 'De']
tran_det.input :language_to, :collection => ['Gr', 'En', 'Fr', 'De']
tran_det.input :price
end
end
f.actions
end
controller do
before_filter { #page_title = :translation_type }
end
I don't need a section for translation_detail so I have omited app/admin/translation_detail.rb
I want to have nested forms of translation_detail in my translation_type form. Using the code above creates the nested form but after submit the attributes of translation_detail are not saved. Furthermore when I try to update or delete a translation_detail this message is shown
Couldn't find TranslationDetail with ID=* for TranslationType with ID=*
How can this be fixed?

It seem that this line
attr_accessor :id, :language_from, :language_to, :price
in app/models/translation_detail.rb, was causing the error, but I am not really sure why.

I ran into the same problem when saving a field that previously wasn't being saved and did not exist in the DB. I had to remove the attr_accessor :fieldName from the model file to make it permanent.
As this answers states: attr_accessor on Rails is only ever used if you don't want the attributes to be saved to the database, only stored temporarily as part of an instance of that Model.
What probably was happening in the question's example is that it could not save the TranslationDetail because everything except for its relationship to TranslationType was being discarded before saving.

Related

Rails, Active admin, nested form, dynamic label value - issue with the form object

I have three models:
class Request < ActiveRecord::Base
belongs_to :scenario
belongs_to :location
has_many :actions, :foreign_key => 'request_id'
accepts_nested_attributes_for :actions, :allow_destroy => true
end
class Action < ActiveRecord::Base
belongs_to :request
belongs_to :scenario_step
end
class ScenarioStep < ActiveRecord::Base
belongs_to :scenario
has_many :actions
end
Using Active Admin I want to update information about action taken in response to a request. To do that I am using nested form:
ActiveAdmin.register Request do
permit_params :scenario_id, :location_id,
actions_attributes: [:scenario_step_id, :description]
form(:html => {:multipart => true}) do |f|
f.inputs "Request details" do
f.input :status
panel 'Steps' do
"Text ..."
end
f.has_many :actions, heading: 'Steps to follow', allow_destroy: false, new_record: true do |ff|
ff.input :description, label: ff.object.scenario_step_id, hint: 'Text'
ff.input :scenario_step_id
end
para "Press cancel to return to the list without saving."
f.actions
end
end
end
Everything seems to be fine except of label (or hint). As a value I want to put there related data from a table scenario_steps.
As you can see I currently try to at least print the value of scenario_step_id that should be available in the object form (ff.object.scenario_step_id) but it is not working (I have such column in actions table). On the other hand, next line: ff.input :scenario_step_id loads appropriate data into input field.
Can somebody give ma a hint what am I doing wrong?
Here is what I was missing (part of formtastic documentation):
Values for labels/hints/actions are can take values: String (explicit
value), Symbol (i18n-lookup-key relative to the current "type", e.g.
actions:), true (force I18n lookup), false (force no I18n lookup).
Titles (legends) can only take: String and Symbol - true/false have no
meaning.
So small change (to_s) in line below makes huge difference :)
ff.input :description, label: ff.object.scenario_step_id.to_s, hint: 'Text'

Enum selection in ActiveAdmin for a Engine Model

I continue to get a undefined method error when attempting to get the ActiveAdmin form to use a selection box based of the keys for an enum properties for an object. Following the suggested method on stack overflow to configure active admin forms for enums seems to get me half way there although the engine aspect of my object seems to make the enum attribute through the NoMethodError exception.
#/lib/book_store/admin/books
if defined?(ActiveAdmin)
ActiveAdmin.register BookStore::Book, as: 'Book' do
# customize your resource here
form do |f|
f.semantic_errors # shows errors on :base
f.inputs do
f.input :cover_type, as: :select, collection: BookStore::Book.cover_type.keys
end
f.actions # adds the 'Submit' and 'Cancel' buttons
end
permit_params :name, :lead, :excerpt, :description, :price, :slug, :cover_type, :num_pages, :size, :cover_image, :author, :author_id, :category
end
end
#app/models/book_store/book.rb
module BookStore
class Book < ActiveRecord::Base
belongs_to :author
belongs_to :category
enum cover_type: [:soft, :hard]
end
end
gets the following error
undefined method `cover_type' for #<Class:0x007fe685217af0>
here is the full stack trace
I think cover_type should be pluralized.
f.input :cover_type, as: :select, collection: BookStore::Book.cover_types.keys
Almost a related answer...
You can use enumerize gem and activeadmin addons to handle enumerations nicely.

ActiveAdmin Form not saving nested object

Using ActiveAdmin with Rails 4, I have two models, Document and Attachment with a one-to-many relationship between them.
# models/document.rb
class Document < ActiveRecord::Base
has_many :attachments
accepts_nested_attributes_for :attachments
end
# models/attachment.rb
class Attachment < ActiveRecord::Base
belongs_to :document
end
I registered the models and included permit_params for all the fields in each.
Now I used has_many in the form view in the below code. This shows an option to add Attachments and it work just fine.
# admin/document.rb
ActiveAdmin.register Document do
permit_params :title, :description, :date, :category_id
show do |doc|
attributes_table do
row :title
row :description
row :attachments do
doc.attachments.map(&:document_path).join("<br />").html_safe
end
end
end
form do |f|
f.inputs "Details" do
f.input :title
f.input :description
f.input :category
f.has_many :attachments, :allow_destroy => true do |cf|
cf.input :document_path # which is a field in the Attachment model
end
end
f.actions
end
end
However, when I submit the form, the document object is saved but no attachment objects are saved with it. As much as I understand it should create as many attachments I added in the form and pass in their document_id attribute the created document ID. Unfortunately this is not happening leaving the Attachment row "EMPTY" in the show view. Am I missing something?
Thanks in advance.
You forgot to permit attachments_attributes.
In order to use accepts_nested_attribute_for with Strong Parameters, you will need to specify which nested attributes should be whitelisted.
More info http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

ActiveAdmin forms with has_many - belongs_to relationships?

I have the models Home and Photo, which have a has_many - belongs_to relationship (a polymorphic relationship, but I dont think that matters in this case). I am now setting up active admin and I would like admins to be able to add photos to homes from the homes form.
The photos are managed by the CarrierWave gem, which I dont know if will make the problem easier or harder.
How can I include form fields for a different model in the Active Admin Home form? Any experience doing something like this?
class Home < ActiveRecord::Base
validates :name, :presence => true,
:length => { :maximum => 100 }
validates :description, :presence => true
has_many :photos, :as => :photographable
end
class Photo < ActiveRecord::Base
belongs_to :photographable, :polymorphic => true
mount_uploader :image, ImageUploader
end
Try something like this in app/admin/home.rb:
form do |f|
f.inputs "Details" do
f.name
end
f.has_many :photos do |photo|
photo.inputs "Photos" do
photo.input :field_name
#repeat as necessary for all fields
end
end
end
Make sure to have this in your home model:
accepts_nested_attributes_for :photos
I modified this from another stack overflow question: How to use ActiveAdmin on models using has_many through association?
You could try this:
form do |f|
f.semantic_errors # shows errors on :base
f.inputs # builds an input field for every attribute
f.inputs 'Photos' do
f.has_many :photos, new_record: false do |p|
p.input :field_name
# or maybe even
p.input :id, label: 'Photo Name', as: :select, collection: Photo.all
end
end
f.actions # adds the 'Submit' and 'Cancel' buttons
end
Also, you can look at https://github.com/activeadmin/activeadmin/blob/master/docs/5-forms.md (See Nested Resources)
I guess you are looking for a form for a nested model. Take a look at following railscasts.
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
I cannot tell you much about active_admin, but I think this should not make a difference in handling the nested model.
I have a has_one model, like this:
f.has_many :addresses do |a|
a.inputs "Address" do
a.input :street ... etc.
While this correctly reflects our associations for Address (which is a polymorphic model) using f.has_one fails. So I changed over to has_many and all's well. Except now we have to prevent our users from creating multiple addresses for the same entity.

Nested form in active_admin with select or create option

We are using active_admin for our administration backend.
We have a model "App" that :belongs_to model "Publisher":
class App < ActiveRecord::Base
belongs_to :publisher
end
class Publisher < ActiveRecord::Base
has_many :apps
end
When creating a new entry for the "App" model I want to have the option to either select an existing publisher or (if the publisher is not yet created) to create a new publisher in the same (nested) form (or at least without leaving the page).
Is there a way to do this in active_admin?
Here's what we have so far (in admin/app.rb):
form :html => { :enctype => "multipart/form-data" } do |f|
f.inputs do
f.input :title
...
end
f.inputs do
f.semantic_fields_for :publisher do |p| # this is for has_many assocs, right?
p.input :name
end
end
f.buttons
end
After hours of searching, I'd appreciate any hint... Thanks!
First, make sure that in your Publisher model you have the right permissions for the associated object:
class App < ActiveRecord::Base
attr_accessible :publisher_attributes
belongs_to :publisher
accepts_nested_attributes_for :publisher, reject_if: :all_blank
end
Then in your ActiveAdmin file:
form do |f|
f.inputs do
f.input :title
# ...
end
f.inputs do
# Output the collection to select from the existing publishers
f.input :publisher # It's that simple :)
# Then the form to create a new one
f.object.publisher.build # Needed to create the new instance
f.semantic_fields_for :publisher do |p|
p.input :name
end
end
f.buttons
end
I'm using a slightly different setup in my app (a has_and_belongs_to_many relationship instead), but I managed to get it working for me. Let me know if this code outputs any errors.
The form_builder class supports a method called has_many.
f.inputs do
f.has_many :publisher do |p|
p.input :name
end
end
That should do the job.
Update: I re-read your question and this only allows to add a new publisher, I am not sure how to have a select or create though.
According to ActiveAdmin: http://activeadmin.info/docs/5-forms.html
You just need to do as below:
f.input :publisher
I've found you need to do 3 things.
Add semantic fields for the form
f.semantic_fields_for :publisher do |j|
j.input :name
end
Add a nested_belongs_to statement to the controller
controller do
nested_belongs_to :publisher, optional: true
end
Update your permitted parameters on the controller to accept the parameters, using the keyword attributes
permit_params publisher_attributes:[:id, :name]

Resources