It's the third day I'm crushing on Active Admin.
I have #survey that has_many :questions and each question has_many :answers - they are actually variants users can choose from.
But still I cant put it to work, it just doesn't create anything deeper then 1 level:
even the form works properly, but nothing is created.
I have the following clases Course->Sections->Lessons.
I did the following:
form do |f|
f.inputs "Details" do
f.input :instructor, :as => :select
f.input :title
f.input :name
f.input :price
f.input :discount
f.input :slug
f.inputs "Sections" do
f.has_many :sections, :header=>"" do |section|
section.input :name
section.input :position
if section.object.id
section.input :_destroy, :as=>:boolean, :required => false, :label=>'Remove'
end
section.has_many :lessons, :header=>"Lessons" do |lesson|
lesson.input :title
lesson.input :position
lesson.input :duration
lesson.input :_destroy, :as=>:boolean, :required => false, :label=>'Remove'
end
end
end
end
f.buttons
end
My models are as follow:
class Course < ActiveRecord::Base
has_many :sections, :dependent => :delete_all
accepts_nested_attributes_for :sections, :allow_destroy => true
attr_accessible :sections_attributes
....
class Section < ActiveRecord::Base
belongs_to :course
has_many :lessons, :dependent => :delete_all
attr_accessible :course_id, :name, :position
accepts_nested_attributes_for :lessons, :allow_destroy => true
attr_accessible :lessons_attributes
....
class Lesson < ActiveRecord::Base
belongs_to :section
attr_accessible :duration, :position, :section_id, :title
....
And it works great! I don't know what happens if I go more levels deeper.
Related
I have model of course, every course has many units, every unit has many videos and has one quiz and finally every quiz has many questions.
When I try to add new course or edit one, this is the error I get:
undefined method `has_one' for #
Did you mean? has_many
This are my models:
Course.rb
class Course < ApplicationRecord
validates_presence_of :title
validates_presence_of :author
has_many :units, dependent: :destroy, autosave: true
accepts_nested_attributes_for :units, allow_destroy: true
acts_as_paranoid
end
Unit.rb
class Unit < ApplicationRecord
validates_presence_of :name
validates_presence_of :course_id
belongs_to :course
has_many :videos, dependent: :destroy, autosave: true
has_one :quiz, dependent: :destroy, autosave: true
accepts_nested_attributes_for :videos, allow_destroy: true
accepts_nested_attributes_for :quiz, allow_destroy: true
acts_as_paranoid
end
Video.rb
class Video < ApplicationRecord
validates :data ,presence: true
validates_presence_of :unit
validates_presence_of :unit_id
validates_presence_of :name
belongs_to :unit
acts_as_paranoid
end
Quiz.rb
class Quiz < ApplicationRecord
validates_presence_of :name
validates_presence_of :unit
validates_presence_of :unit_id
belongs_to :unit
has_many :questions, :dependent => :destroy, :autosave => true
accepts_nested_attributes_for :questions, allow_destroy: true
acts_as_paranoid
end
Question.rb
class Question < ApplicationRecord
validates :question ,presence: true
validates :answer1 ,presence: true
validates :answer2 ,presence: true
validates :answer3 ,presence: true
validates :answer4 ,presence: true
validates :correct ,presence: true
validates_presence_of :segment
belongs_to :quiz
acts_as_paranoid
end
This is the courses.rb in active admin:
ActiveAdmin.register Course do
permit_params :id, :title, :author, :course_details, :course_expectations, :course_time, :course_topics, :course_additional_resources,
units_attributes: [:id, :name, :_destroy, :_create, :_update,
videos_attributes: [:id, :name, :data],
quiz_attributes: [:id, :name,
questions_attributes: [:id, :question, :answer1, :answer2, :answer3, :answer4, :correct, :_destroy, :_create, :_update]]]
config.sort_order = 'id_asc'
active_admin_paranoia
# /admin/course/:id/units
member_action :units do
#units = resource.units
# This will render app/views/admin/courses/units.html.erb
end
index do
column :id
column :title
column :author
actions
end
show do
panel "About this course" do
div do
label "Course Topics:"
span course.course_topics
end
div do
label "Course Expectations:"
span course.course_expectations
end
div do
label "Time:"
span course.course_time
end
div do
label "Additional Resources:"
span course.course_additional_resources
end
end
panel "Course Overview" do
table_for course.units do
column "Unit name", :name
column(:videos) {|unit|
table_for unit.videos do
column :id
column :name
column :data
end
}
column(:quiz) { |unit|
if unit.quiz
table_for unit.quiz do
column :id
column :name
column :question
column :answer1
column :answer2
column :answer3
column :answer4
column :correct
end
else
'No Quiz'
end
}
end
end
active_admin_comments
end
sidebar "Course Units", only: :show do
# sidebar "Course Details", only: :show do
# attributes_table_for course do
# row :title
# row :author
# end
table_for Unit.joins(:course).where(:course_id => course.id) do |t|
t.column("Title") { |unit| unit.name }
end
end
form do |f|
tabs do
tab 'Basic Info' do
f.inputs "Course details" do
f.input :title
f.input :author
f.input :course_topics
f.input :course_expectations
f.input :course_time
f.input :course_additional_resources
end
end
tab 'Content' do
f.inputs "Units" do
f.has_many :units, heading: false, allow_destroy: true do |unit|
unit.input :name
unit.has_many :videos, heading: false, allow_destroy: true do |video|
video.input :name
video.input :data, label: 'Url', :as => :string, input_html: { class: 'video-tab' }
end
unit.has_one :quiz, heading: false, allow_destroy: true do |quiz|
quiz.has_many :questions, heading: false, allow_destroy: true do |q|
q.input :question, input_html: { class: 'quiz-tab' }
q.input :answer1, input_html: { class: 'quiz-tab' }
q.input :answer2, input_html: { class: 'quiz-tab' }
q.input :answer3, input_html: { class: 'quiz-tab' }
q.input :answer4, input_html: { class: 'quiz-tab' }
q.input :correct, input_html: { class: 'quiz-tab' }, as: :select, collection: [1,2,3,4]
end
end
end
end
end
end
f.actions
end
end
Sorry for my English
I have a create many to many association between articles and categories
this is my article model
class Article < ActiveRecord::Base
has_many :categorizations
has_many :categories, through: :categorizations
end
this is my category model
class category < ActiveRecord::Base
has_many :categorizations
has_many :articles, through: :categorizations
end
in this my categorization model
class Categorizations < ActiveRecord::Base
belongs_to :article
belongs_to :category
end
then I have create the categories names in the Seed file
but I try to get the categories in a select but I get this Error
undefined method category_id' for <%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %>
Just change <%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %> to <%= f.collection_select :category_ids, Category.all, :id, :name, :include_blank => true %>
I have models product and product images. Product_images is a paperclip model. Product has many product_images. I am making an Active Admin form which uploads multiple images and shows these images to the Products view page.
However, when I save the product. The product table is updated, but not the product_image table. Image attaching normally, but I can't update fields of already uploaded image.
class Product < ActiveRecord::Base
attr_accessible :name, :product_images_attributes
has_many :product_images, :dependent => :destroy
accepts_nested_attributes_for :product_images, :reject_if => lambda { |t| t['product_image'].nil? }, :allow_destroy => true
end
class ProductImage < ActiveRecord::Base
attr_accessible :name, :style
attr_accessible :image
belongs_to :product
has_attached_file :image, :styles => { :small => "150x150>", :large => "320x240>" }
validates_attachment_presence :image
end
ActiveAdmin.register Product do
form :html => { :multipart => true } do |f|
f.inputs "Admin Details" do
f.input :name
end
f.inputs "Product images" do
f.has_many :product_images do |p|
p.input :style, :as => :select, :collection => Image::STYLES, :include_blank => false
p.input :image, :as => :file, :label => "Image",:hint => p.object.image.nil? ? p.template.content_tag(:span, "No Image Yet") : p.template.image_tag(p.object.image.url(:small))
p.input :_destroy, :as=>:boolean, :required => false, :label => 'Remove image'
end
end
f.buttons
end
UPDATE
In the products model I do:
after_update :check
def check
if ProductImage.find_by_product_id(self.id).changed?
raise "image"
else
raise "fail"
end
end
and it's alway raise "fail"
I got the same error using rails 4.1. Just solved this.
I noticed that warnings in my output:
Unpermitted parameters: _destroy, id
Unpermitted parameters: _destroy, id
Unpermitted parameters: _destroy, id
So I just passed them to permit_params:
permit_params assets_attributes: [:image, :image_file_name, :image_content_type, :image_file_size, :image_updated_at, :_destroy, :id]
to AA's resource page. And it worked.
I hope it will help.
If not - here is my listings.
ActiveAdmin.register Product do
permit_params :name, :description, :price, :brand_id, :category_id, assets_attributes: [:image, :image_file_name, :image_content_type, :image_file_size, :image_updated_at, :_destroy, :id]
form multipart: true do |f|
f.inputs "Детали" do
f.input :category_id, as: :select, collection: Category.all, include_blank: false
f.input :brand_id, as: :select, collection: Brand.all, include_blank: false
f.input :name
f.input :description
f.input :price
end
f.inputs 'Фотографии' do
f.has_many :assets, allow_destroy: true, heading: 'Фото', new_record: false do |fasset|
fasset.input :image, as: :file, hint: fasset.template.image_tag(fasset.object.image.url(:thumb))
end
end
f.actions
end
end
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :brand
has_many :assets, dependent: :destroy, autosave: true
accepts_nested_attributes_for :assets, allow_destroy: true,
:reject_if => lambda { |attributes| attributes[:image].blank? }
validate :name, presence: true
validate :description, presence: true
validate :price, presence: true
end
class Asset < ActiveRecord::Base
belongs_to :product
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
validates_with AttachmentPresenceValidator, :attributes => :image
end
You can configure ActiveRecord to cascade-save changes to items in a collection for a model by adding the :autosave => true option when declaring the association.
Try:
has_many :product_images, :dependent => :destroy, :autosave => true
Also, you can save the table data on association in the after_save callback like this:
class Product < ActiveRecord::Base
attr_accessible :name, :product_images_attributes
has_many :product_images, :dependent => :destroy
accepts_nested_attributes_for :product_images, :reject_if => lambda { |t| t['product_image'].nil? }, :allow_destroy => true
after_save :do_product_image_update
private
def do_product_image_update
self.product_images.save
end
end
Given the following Model, Relationship & Edit Form
class User < ActiveRecord::Base
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
end
<%= form_for(#topic) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :Followers %>
<%= f.fields_for :relationships do |builder| %>
<%= f.collection_select :follower_id, User.all( order: "name"), :id, :name, include_blank: true %>
<% end %>
<%= f.submit "Save Changes" %></div>
<% end %>
class Relationship < ActiveRecord::Base
attr_accessible :followed_id
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
validates :follower_id, presence: true
validates :followed_id, presence: true
end
In this case, the fields for relationships appear in the edit form for a given user. Thus, they can manage all of their followers. But the problem is, on the edit page, the users show up in the order they were added. Is there any way to sort them such that they appear alphabetically by name, despite the fact that the :relationships association has only an id?
I have the following Models:
class Topic < ActiveRecord::Base
has_many :posts, :dependent => :destroy
attr_accessible :name, :post_id
end
class Post < ActiveRecord::Base
belongs_to :topic, :touch => true
has_many :comments, :dependent => destroy
accepts_nested_attributes_for :topic, :comments
attr_accessible :name, :title, :content, :topic, :topic_attributes
end
class Comment < ActiveRecord::Base
belongs_to :Post
end
Is this simple form valid? Can I access 2 nested Models at the same time?
simple_form_for #post do |f|
f.simple_fields_for :topic do |topic_form|
topic_form.input :name
end
f.simple_fields_for :comment do |comment_form|
comment_form.input :text
end
end
Thanks
Try this
simple_form_for #post do |f|
f.simple_fields_for #post.topic do |topic_form|
topic_form.input :name
end
f.simple_fields_for #post.comments do |comment_form|
comment_form.input :text
end
end