Respected ppl ...
i have these models :
class SanctionedPost < ActiveRecord::Base
attr_accessible :hospital_id, :sanctioned_posts, :designation_id
column :district_id
belongs_to:designation
belongs_to:hospital
belongs_to:district
belongs_to:division
end
class Hospital < ActiveRecord::Base
attr_accessible :beds, :fax_no, :hospital_name, :phone_no, :district_id, :institution_type_id, :location_id, :division_id, :block_id, :hospital_type_id, :IsAdministrativeLocation, :IsTribal, :latitude, :longitude
belongs_to:district
belongs_to:division
belongs_to:block
has_many:sanctioned_posts
end
class Division < ActiveRecord::Base
attr_accessible :division_name, :state_id
has_many:health_dept_locations
belongs_to:state
has_many:districts
has_many:hospitals
has_many:sanctioned_posts
validates_associated :districts
end
I want to be able to create dropdowns in my sanctioned_posts for such that divisions narrows down the districts which narrows down the blocks which narrows down to hospitals ...
(so that i dont have to select from a million hospitals ...) ...
I have tried everything from http://railscasts.com/episodes/88-dynamic-select-menus-revised and http://railscasts.com/episodes/193-tableless-model still to no avail ...
====================================
im using simple form ... and this allowed me to accomplish a similar task for the hospitals create form ...
<%= f.association :division,label_method: :division_name, value_method: :id, include_blank: false%>
<%= f.input :district_id do %>
<%= f.grouped_collection_select :district_id, Division.order(:division_name), :districts, :division_name, :id, :district_name, include_blank: true, label: 'District' %>
<% end %>
<%= f.input :block_id do %>
<%= f.grouped_collection_select :block_id, District.order(:district_name), :blocks, :district_name, :id, :block_name, include_blank: true, label: 'Block' %>
<% end %>
(+ the accompanying coffeescript... )
But in my current scenario im not able to do the same ...since im not storing division,district,block id in the sanctioned_posts model .... but i believe the hospital_id would be somewhat helpful in this context ....
Thnx very much in advance :) ...
Regards
Why not use CoffeeScript and JQuery to do REST requests on the index method and you can configure your routes accordingly?
Example: States have schools, schools have students
States have_many schools, schools have_many students
Select first state of Illinois. Illinois has ID of 11
get request to /states/11/schools.json
SchoolsController < ApplicationController
responds_to :json
def index
states = State.find(params[:id})
respond_with states.schools
end
end
Related
I have a model Food that has many food_varients. The FoodVarient is a model that will be set by the admin of the system. For Example the food varients could be Hot,Spicy,Extra Cheese, etc. And a food can have these varients.
Since, Food has_many food_varients, I decided to use nested form to allow the admin to create a new food item and also select food_varients that the food might have from the pre-defined food_varients created before-hand by the admin.
This is what my FoodsController looks like:
class FoodsController < DashboardBaseController
# GET /foods/new
def new
#food = current_department.foods.new
#food.food_varients.build
end
# GET /foods/1/edit
def edit
end
def food_params
params.require(:food).permit(:name, :description,food_varients_attributes[:id,:varient_id])
end
end
I have also accepted the nested attribute in my Food.rb file as follows:
class Food < ApplicationRecord
has_many :food_varients, dependent: :destroy
has_many :varients, through: :food_varients, dependent: :destroy
accepts_nested_attributes_for :food_varients, reject_if: proc { |attributes| attributes['varient_id'] == "0" }
And this is what my form looks like, to add food:
= form_for #food do |f|
.field.form-group
= f.label :name
= f.text_field :name, class: 'form-control', tabindex: 1
.field.form-group
= f.label :description
= f.text_area :description, class: 'form-control', tabindex: 3
........
//**Nested Form Starts from here**
- current_department.varients.each do |varient|
= f.fields_for :food_varients do |g|
= g.label :varient_id, varient.title
= g.check_box :varient_id,{} ,varient.id
I created the nested form by looping around each instance of the Varient model, that was created by the admin, and giving the admin the options to add the food_varients as the new food item is being created.
Problem:
The create is working fine, and the nested attributes are being saved as expected.
But, when i try to edit the food item, the nested form is showing duplicate fields.
For Example: If originally the food was set to have varients (sweet, and sour). Now, the edit page of the food item is showing me 4 fields instead of the two, with two checked sweet and sour fields, and two unchecked. sweet and sour fields.
Is there a different approach that i must be trying? Because ever other example that i see, makes the use of text_fields to save the nested attribute dynamically, while I am looping through the already existing varient instance.
You don't need to use nested attributes at all here. Just use the collection helpers along with the varient_ids= setter:
= form_for #food do |f|
.field.form-group
= f.label :name
= f.text_field :name, class: 'form-control', tabindex: 1
.field.form-group
= f.label :description
= f.text_area :description, class: 'form-control', tabindex: 3
.field.form-group
= f.label :varient_ids
= f.collection_select :varient_ids, Varient.all, :id, :name
class FoodsController < DashboardBaseController
# GET /foods/new
def new
#food = current_department.foods.new
end
# ...
def food_params
params.require(:food).permit(:name, :description, varient_ids: [])
end
end
Rails will automatically add/destroy rows on the join table. The correct spelling is also Variant:
variant (plural variants)
Something that is slightly different from a type or norm.
- https://en.wiktionary.org/wiki/variant#English
I'm trying to setup a Rails 4 form to display all of the different store branches in a collection_select, followed by a grouped_collection_select displaying all of the possible combinations of storage types for each branch. I then want to filter out the storage types not available at a certain branch using CoffeeScript, as shown in Railscasts #88 (this is not an issue)
However, I can't figure out how to populate the grouped select pre-filtering. I need to go through the joining table StorageTypeBranch to find the storage types available at each branch.
My models:
class StorageType < ActiveRecord::Base
has_many :storage_type_branches
has_many :branches, through: :storage_type_branches
end
class Branch < ActiveRecord::Base
has_many :storage_type_branches
has_many :storage_types, through: :storage_type_branches
end
# Joining table
class StorageTypeBranch < ActiveRecord::Base
belongs_to :storage_type
belongs_to :branch
end
Controller:
def new
#branches = Branch.where(is_active: true).order(:name)
# Doesn't work because it has to be called on one instance of the model.
# What should this be?
#storage_types = #branches.storage_types.all
end
View:
<%= f.label :branch_id %>
<%= f.collection_select :branch_id, #branches, :id, :name, prompt: '<--- Select a Branch --->' %>
<br/>
<%= f.label :storage_type_id %>
# Where I want the grouped select to be
<%= f.grouped_collection_select #storage_types %>
The end result I'm looking to achieve:
Any help would really be appreciated.
If you want all branch types for the list of branches:
#storage_types = #branches.flat_map{|branch| branch.storage_types}.uniq # Array
If you want them for each branch:
#storage_types = Hash[#branches.map{|branch| [branch, branch.storage_types]}]
# {branch1 => [storage_typeA, storage_typeB], branch2 => [storage_typeC, storageTypeE]}
You can then group the collection with something like:
<%= f.input :storage_types, :as => :grouped_select, :collection => #storage_types, :group_method => :first, :group_label_method => :last %>
For more alternative see: simple_form: how to create a grouped select box?
I'm building a daily deal Rails app to learn RoR.
I am facing a problem for the past few hours : i can't get a model's attribute of an other associated model on active admin. Let me show you exactly the problem :
I have two models: Brand (i.e the brand of the deal) and Deal. A deal belongs to a Brand but a Brand can have many Deals.
models/deal.rb is like this:
class Deal < ActiveRecord::Base
belongs_to :brand
and we have models/brand.rb:
class Brand < ActiveRecord::Base
has_many :deals
attr_accessible :name
And i did the t.belongs_to in my migrations so this is ok.
In Active Admin's Deals' create form , i type, as admin, which brand the deal is associated with:
admin/game.rb
ActiveAdmin.register Deal do
# -- Form -----------------------------------------------------------
form do |f|
f.inputs "Brand (i.e. client)" do
f.input :brand_id, :label => "Select a brand:", :as => :select, :collection => Brand.all
end
it works great, and i can create Deals with a certain brand.
but I CAN'T manage to display the NAME of the Brand in my list of Deals:
ActiveAdmin.register Deal do
index do
selectable_column
# id_column
column :title
column :deal_amount
column :brand do |deal|
link_to deal.brand.name
end
...doesn't work.
How can I do that ?
I tried everything but i basically don't know how to fetch the name of a Brand given it matches the brand_id in the Deal's table.
Any help appreciated.
show do |f|
panel "Subject" do
attributes_table_for f, :name, :description, :is_visible
end
panel "Pages in List View" do
table_for(f.pages) do |page|
column :name
column :permalink
column :is_visible
end
end
panel "Pages in View " do
div_for(f.pages) do |page|
panel page.name do
attributes_table_for page, :name, :description, :is_visible
end
end
end
end
end
You can do nested relations in same style as parent model
A couple things seem missing:
class Deal < ActiveRecord::Base
belongs_to :brands, foreign_key: :brand_id, class_name: 'Brand'
end
This is assuming that you mean partner to be a Brand and your schema uses brand_id for that relationship.
In your form, you can simply use:
form do |f|
f.inputs "Brand (i.e. client)" do
f.input :partner, label: 'Select a brand:'
end
end
Your link_to call won't actually link to a url the way you have it.
column :brand do |deal|
link_to deal.partner.name, admin_brand_path(deal.partner)
# or simpler
auto_link deal.partner
end
I would highly recommend trying to be consistent in your naming, as it will make things a lot less confusing and will require less code to make things work. i.e.
class Deal < ActiveRecord::Base
belongs_to :brand
end
f.input :brand, label: 'Select a brand:'
auto_link deal.brand
And your DB column can still be named brand_id.
I know that one way to add/edit/delete (nested) records using a form is by using :accepts_nested_attributes_for: in the the corresponding models. However, when this nesting extends to about 4 levels (because of the normalization of the database), and I want to display all of these levels for editing on the website, this method seems to be rather cumbersome (and ugly).
I was wondering whether there is a way to define 'super' models with getter and setter methods that allow me to edit the necessary data in one place . As a simplified example, consider:
class Person < ActiveRecord::Base
attr_accessible :name, :age
has_one :address
end
class Address < ActiveRecord::Base
attr_accessible :street, :zip, :country
belongs_to :person
end
I would like to show/edit/update/etc the name, age, street, zip, country in one form. It's clear how to do this using accepts_nested_attributes_for. But I would like to have a class, say, PersonalInformation, that combines the fields name, age, street, zip, country from both classes by passing in the id from Person. I would then like to use this class as an interface for the website.
Something like a Form Object as described here:
http://robots.thoughtbot.com/activemodel-form-objects
I've been trying various implementations and haven't found the perfect solution but they do simplify "bringing a bunch of models together". The codeclimate blog also touches on it (item #3) at:
http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models
The codeclimate post uses an older method of including the ActiveModel modules (no need to include them individually unless you want to now) but the concept is the same.
I would recommend the simple form gem. I modified an example from their docs to reflect your models that does exactly what you want:
Models:
class Person < ActiveRecord::Base
attr_accessible :name, :age
has_one :address
end
class Address < ActiveRecord::Base
attr_accessible :street, :zip, :country
belongs_to :person
end
View:
<%= simple_form_for #person do |f| %>
<%= f.input :name %>
<%= f.input :age %>
<%= f.association :street %>
<%= f.association :zip %>
<%= f.association :country %>
<%= f.button :submit %>
<% end %>
You could use virtual attributes on the Person model and put custom assignment logic within the getters/setters for each of the editable Address attributes.
class Person < ActiveRecord::Base
attr_accessible :name, :age
has_one :address
def street=(new_street)
# ...
end
end
This would likely end up being more complex in the long run.
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]