I would like to make a dynamic select option via Activeadmin's formtastic like so:
form do |f|
f.inputs "Exam Registration Details" do
f.input :user_id, :as => :select, :collection => User.where(:admin => 'false')
#selects user from list. WORKING
f.input :student_id, :as => :select, :collection => Student.joins(lessons: :user)
#collection of students will change to students who have lessons with chosen user. NOT WORKING, returns all students who have lessons.
f.input :lesson_id, :as => :select, :collection => Lesson.joins(:student, :user)
#collection of lessons will change to reflect lessons connected by chosen user and student. NOT WORKING, returns all lessons.
end
f.buttons
end
My amateurish code is obviously not working as I intended it to. What changes should I make?
I have 4 models as below:
class Student < ActiveRecord::Base
has_many :lessons
has_many :users, through: :lessons
has_many :exam_registrations, through: :lessons
class Lesson < ActiveRecord::Base
belongs_to :user
belongs_to :student
belongs_to :exam_registration
class User < ActiveRecord::Base
has_many :lessons
has_many :students, through: :lessons
has_many :exam_registrations, through: :lessons
class ExamRegistration < ActiveRecord::Base
has_many :lessons
has_many :users, through: :lessons
has_many :students, through: :lessons
SOLVED
For anyone else wrestling with the same problem, look at this railscast
here's how I implemented multiple dynamic select menus in activeadmin:
config/initializers/active_admin.rb
config.register_javascript 'exam_registrations.js.coffee'
app/admin/exam_registrations.rb
form do |f|
f.inputs "Exam Registration Details" do
f.input :user_id, :label => 'Teacher', :as => :select, :collection => User.where(:admin => 'false', :active => true).order(:name), :include_blank => true
f.input :student_id, :hint => 'Students grouped by teacher names', :as => :select, :collection => option_groups_from_collection_for_select(User.where(:admin => false, :active => true).order(:name), :students, :name, :id, :name)
f.input :lesson_id, :hint => 'Lessons grouped by student names', :as => :select, :collection => option_groups_from_collection_for_select(Student.where(:active => true).order(:name), :lessons, :name, :id, :name)
end
f.buttons
end
app/assets/javascripts/exam_registrations.js.coffee
#first menu
jQuery ->
$('#exam_registration_student_id').parent().hide()
students = $('#exam_registration_student_id').html()
$('#exam_registration_user_id').change ->
user = $('#exam_registration_user_id :selected').text()
escaped_user = user.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g, '\\$1')
options = $(students).filter("optgroup[label='#{escaped_user}']").html()
if options
$('#exam_registration_student_id').html(options)
$('#exam_registration_student_id').parent().show()
else
$('#exam_registration_student_id').empty()
$('#exam_registration_lesson_id').empty()
# second menu
$('#exam_registration_lesson_id').parent().hide()
lessons = $('#exam_registration_lesson_id').html()
$('#exam_registration_student_id').click ->
student = $('#exam_registration_student_id :selected').text()
escaped_student = student.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g, '\\$1')
options = $(lessons).filter("optgroup[label='#{escaped_student}']").html()
if options
$('#exam_registration_lesson_id').html(options)
$('#exam_registration_lesson_id').parent().show()
else
$('#exam_registration_lesson_id').empty()
restart the server and the menus work!
Related
Using simple_form to build a nested form for a WorkoutSet model with the following fields:
intro_video
get_ready
outro_video
WorkoutStep (another nested model)
I want to be able to select an intro_video out of a select
As WorkoutSet is inside Workout, the forms look like this:
WorkoutSet.rb
class WorkoutSet < ActiveRecord::Base
has_and_belongs_to_many :workout_steps, :join_table => :sets_steps, dependent: :destroy
has_and_belongs_to_many :workouts, :join_table => :workout_sessions
accepts_nested_attributes_for :workout_steps, allow_destroy: true
has_one :intro_video_usage, class_name: 'VideoUsage::Intro', as: :parent, dependent: :destroy
has_one :intro_video, through: :intro_video_usage, source: :video
accepts_nested_attributes_for :intro_video
has_one :get_ready_video_usage, class_name: 'VideoUsage::GetReady', as: :parent, dependent: :destroy
has_one :get_ready_video, through: :get_ready_video_usage, source: :video
has_one :congrats_video_usage, class_name: 'VideoUsage::Congratulations', as: :parent, dependent: :destroy
has_one :congrats_video, through: :congrats_video_usage, source: :video
end
_form.html.haml
%h2 Sets
.sets.some{ :style => "margin-left: 25px" }
= f.simple_fields_for :workout_sets do |set|
= render 'workout_set_fields', f: set
.links
.button-row
= link_to_add_association 'add set', f, :workout_sets
_workout_set_fields.html.haml
.nested-fields
%h2 New set - #{link_to_remove_association 'Delete', f}
= f.label :title
= f.text_field :title
= f.input :intro_video, :collection => Video.all, :label_method => :title, :value_method => :id, :include_blank => false
%br
%br
#sets.some{ :style => "margin-left: 25px" }
= f.simple_fields_for :workout_steps do |step|
= render 'workout_step_fields', f: step
.links
.button-row
= link_to_add_association 'add step', f, :workout_steps
The select is rendered and the values looks fine until I save the model whitelisting the following parameters:
params.require(:workout).permit(:title, :pro, :image, warmup_attributes: [:id, :_destroy, {main_video_ids: []}], workout_sets_attributes: [:id, :_destroy, :title, :intro_video, workout_steps_attributes: [:id, :_destroy, {main_video_ids: []}] ])
Also, I notice that in the line f.input :intro_video the parameter being sent is intro_video, instead of intro_video_attributes
Thanks in advance.
I have the following setup:
class User < ActiveRecord::Base
has_many :device_ownerships, :dependent => :destroy
has_many :devices, :through => :device_ownerships
end
class device < ActiveRecord::Base
has_one :device_ownership, :dependent => :destroy
has_one :user, :through => :device_ownership
end
class deviceOwnership < ActiveRecord::Base
belongs_to :user
belongs_to :device
validates_uniqueness_of :device_id, :scope => :user_id
validates_uniqueness_of :user_id, :scope => :device_id
end
I am trying to achieve the following in Active Admin:
In Edit screen
1) List all devices that belong to user with an option to delete the device or destroy the deviceOwnership that connects device to user
2) have an option to create a new pairing user-device from existing devices (by creating new DeviceOwnership).
3) have an option to create new device and add it to user via new DeviceOwnership.
I listed my problems with what I have now in comments below:
ActiveAdmin.register User do
permit_params :email, :password, :password_confirmation, :role,
device_ownerships_attributes: [:device_id, :user_id],
devices_attributes: [:device_identifier]
index do |user|
user.column :email
user.column :current_sign_in_at
user.column :last_sign_in_at
user.column :sign_in_count
user.column :role
actions
end
filter :email
form do |f|
f.inputs "User Details" do
f.input :email
f.input :password
f.input :password_confirmation
f.input :role, as: :radio, collection: {Editor: "editor", Moderator: "moderator", Administrator: "administrator"}
#This one allows to create new devices but also lists all existing devices with option to modify their device_identifier column which I don't want
f.has_many :devices, :allow_destroy => true, :heading => 'Themes', :new_record => true do |cf|
cf.input :device_identifier
end
#This one lists all the devices but no option to remove any of them.
f.input :devices
#This one shows dropdownw with existing devices but allows to swap them
f.has_many :devices, :allow_destroy => true do |device_f|
device_f.input :device_identifier, :as => :select, :collection => device.all.map{ |device| [device.device_identifier] }, include_blank: false,
end
f.actions
end
end
end
The line
f.has_many :devices, :allow_destroy => true, :heading => 'Themes', :new_record => true do |cf|
cf.input :device_identifier
end
looks like it might do the job. You could check whether the cf.object is a new record and only let the user change the device_identifier in that case.
cf.input :device_identifier if cf.object.new_record?
or something like cf.input :device_identifier, input_html: { readonly: !cf.object.new_record? }
What do you think?
Im trying to save a post with category relation.
These are my models
class Post < ActiveRecord::Base
has_many :categorizes
has_many :post_categories, :through=>:categorizes
accepts_nested_attributes_for :post_categories
end
class PostCategory < ActiveRecord::Base
has_many :categorizes
has_many :posts, :through=>:categorizes
end
class Categorize < ActiveRecord::Base
belongs_to :post
belongs_to :post_category
end
and in ActiveAdmin post.rb.
ActiveAdmin.register Post do
permit_params :title, :content, post_category_ids:[:id]
index do
selectable_column
id_column
column :title
column :post_category_id
column :created_at
actions
end
filter :created_at
form do |f|
f.inputs "Post Details" do
f.input :title
f.input :content,:input_html => { :class => "tinymce_editor" }
#f.input :post_categories, :as=> :check_boxes#, :collection => PostCategory.all
end
f.has_many :post_categories ,new_record: false do |c|
c.inputs do
c.input :title
end
end
f.actions
end
controller do
defaults :finder => :find_by_slug_url
end
end
I need to see my all categories from post_categories and i should select more than one.
i check in rails console but the post hasnt any category.
Post.First.post_categories equal to []
Try post_category_attributes instead of post_category_ids
See more here.
Currently I'm making an app for users to create picture albums. The catch is that there can be multiple owners for each album, so in the form to create an album there is a check box portion where you highlight your friends names and "invite them" to be an owner. However, I am having a hard time getting it to work since it's giving me an error in my AlbumsController#create. The error is :
undefined method 'user' for #<Album:0x007fcd9021dd00>
app/controllers/albums_controller.rb:43:in 'create'
Here's my form
<%= form_for ([#user, #album]), :html => { :id => "uploadform" } do |f| %>
<div class="formholder">
<%= f.label :name %>
<%= f.text_field :name %>
<br>
<label>Hosts</label>
<% #user.friends.each do |friend| %>
<%= friend.name %>
<%= check_box_tag 'album[user_ids][]', friend.id, #album.users.include?(friend) %>
<% end %>
<%= f.label :description %>
<%= f.text_area :description %>
<br>
<%=f.submit %>
</div>
<% end %>
The checkboxes return an array of friend.id values that I want to invite to be owners for the album. The tricky part here is that I have a imaginary pending_album column in my join album_user model. Here's what is sending me errors that I can't figure out how to fix:
albums controller
def create
#user = User.find(params[:user_id])
#album = #user.albums.build(params[:album], :status => 'accepted')
#friends = #user.friends.find(params[:album][:user_ids])
for friend in #friends
params[:album1] = {:user_id => friend.id, :album_id => #album.id, :status => 'pending'}
AlbumUser.create(params[:album1])
end
#the next line is where the error occurs. why???
if #user.save
redirect_to user_album_path(#user, #album), notice: 'Album was successfully created.'
else
render action: "new"
end
end
album model
class Album < ActiveRecord::Base
attr_accessible :name, :description, :user_ids
validates_presence_of :name
validates :user, :uniqueness => true
has_many :album_users
has_many :users, :through => :album_users
has_many :photos
end
user model
class User < ActiveRecord::Base
has_secure_password
attr_accessible :email, :name, :password, :password_confirmation, :profilepic
validates_presence_of :password, :on => :create
validates_format_of :name, :with => /[A-Za-z]+/, :on => :create
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
validates_length_of :password, :minimum => 5, :on => :create
# validates :album, :uniqueness => true
has_many :album_users
has_many :albums, :through => :album_users, :conditions => "status = 'accepted'"
has_many :pending_albums, :through => :album_users, :source => :album, :conditions => "status = 'pending'"
accepts_nested_attributes_for :albums
has_many :friendships, :dependent => :destroy
has_many :friends, :through => :friendships, :conditions => "status = 'accepted'"
has_many :requested_friends, :through => :friendships, :source => :friend, :conditions => "status = 'requested'", :order => :created_at
has_many :pending_friends, :through => :friendships, :source => :friend, :conditions => "status = 'pending'", :order => :created_at
has_attached_file :profilepic
before_save { |user| user.email = email.downcase }
def name_with_initial
"#{name}"
end
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
album_user join table model
class AlbumUser < ActiveRecord::Base
attr_accessible :user_ids, :album_id, :status, :user_id
belongs_to :album
belongs_to :user
end
parameters (looks a little fishy... especially since album_id is nil):
{"utf8"=>"✓",
"authenticity_token"=>"xkIi6+1vjEk4yQcFs9vI1uvI29+Gyuenyp71vhpX9Hw=",
"album"=>{"name"=>"123123",
"user_ids"=>["27",
"28"],
"description"=>"123123"},
"commit"=>"Create Album",
"user_id"=>"29",
"album1"=>{"user_id"=>28,
"album_id"=>nil,
"status"=>"pending"}}
I'm not too sure what I'm doing wrong. Can someone help please!!
The error message is:
undefined method 'user' for #<Album:0x007fcd9021dd00>
All right, so something's calling Album#user. Line 46 in the controller is #user.save, so how is user getting called?
class Album < ActiveRecord::Base
attr_accessible :name, :description, :user_ids
validates_presence_of :name
validates :user, :uniqueness => true # <-- bam!
has_many :album_users
has_many :users, :through => :album_users
has_many :photos
end
save triggers validations, including that line right there, which validates that user is unique. Since this is exploding, I'm guessing that user is a column that doesn't exist, either because a) it's not defined in a migration or b) you didn't run the migration.
(As an aside, I'm rather confused as to why you would have a unique user attribute on Album, an AlbumUser model with both user_id and user_ids, and a User model. Maybe it makes sense, but I think it's more likely that it all needs a cleanup.)
Your album really has many several users? Then that should return method "user"? If want that one user owned album you must use belongs_to in your model. Then method "user" will return correct user to album
My application has 3 models : consultant, project and appointment
I am using a nested form with simple_form gem
class Consultant < ActiveRecord::Base
has_many :appointments
end
class Project < ActiveRecord::Base
has_many :appointments, :dependent => :destroy
accepts_nested_attributes_for :appointments, :allow_destroy => true
end
class Appointment < ActiveRecord::Base
belongs_to :consultant
belongs_to :project
end
My form is as follows :
= simple_nested_form_for(#project) do |f|
%div.field
= f.input :name, :label => 'Nom du projet'
= f.simple_fields_for :appointments do |builder|
= render 'appointment_fields', :f => builder
= f.link_to_add "ajouter un consultant", :appointments
%div
%div.actions
= f.submit
with the partial :
%p.fields
= f.input :consultant_id, :input_html => { :class => 'special' }
= f.association :consultant
= f.input :nb_days, :input_html => { :class => 'special',:size => 10 }
= f.input :rate, :input_html => {:size => 10}
= f.link_to_remove "Remove this task"
Is it possible to do something as simple as this with simple_form ?
The answer is YES : it works nicely
The errors is because there is no association called consultant on the model Appointment. Use consultants instead.