ruby on rails save group of checkboxes collection select check box - ruby-on-rails

Good Day
i have model
Food
Dayoffer
Food which is records with all foods in our canteen
class Food < ApplicationRecord
belongs_to :supplier
has_many :dayoffer
end
Dailyoffer is restricted set of foods which are offered on some day.
class Dayoffer < ApplicationRecord
belongs_to :food
end
i dont know how to effectively save choices for day
i have idea to use in form collection_check_boxes but dont know how to process it effectively.
schema of db on
https://gist.github.com/netmoleCBA/089950c54a4b8e066da8afc54fa5a62e

Add a WeekDay model that has many offers and seed seven week days in your database :
in your food form:
<%= f.collection_check_boxes(:week_day_ids, WeekDay.all, :id, :name) do |week_day| %>
<%= week_day.label { week_day.check_box } %>
<% end %>
D'ont forget to add week_day_ids in the controller's strong params
params.require(:food).permit(:name, week_day_ids:[])

Related

Rails: Association between Category, Subcategory, and Lawyer

I have a vast list of Lawyers, Categories, and Subcategories.
Hint (so you could have a clue if my associations are okay)
On Categories Table, I do not want to see a column on Categories Table referencing Subcategories.
On Subcategories Table, I do not want to see a column on Subcategories Table referencing Categories.
Not all Categories has Subcategories. i.e. some don't have subcategories as seen in the picture.
I have 2 separate forms creating category and subcategory.
I added category_id and subcategory_id as foreign keys to my lawyers table. Such that I can choose from lawyers form upon create, the category or subcategory a lawyer will belong to as soon in the image.
Also note: A Subcategory could be created at any time, any day, for Categories not having Subcategory, as well as new Subcategories under Categories already having some Subcategories, and lawyers will be placed under them.
The image is a replica of my index/homepage I am having at the moment, at least before number 6 above takes effect any time any day, and I hope to use loop to make this view happen.
Pictorial understanding of what I am trying to do:
Here are my relationships between 3 models
class Lawyer < ActiveRecord::Base
belongs_to :category
belongs_to :subcategory
end
class Category < ActiveRecord::Base
has_many :lawyers
end
class Subcategory < ActiveRecord::Base
#belongs_to :category #Do I want "category_id" in Subcategories Table?
has_many :lawyers
end
Question
Is my association on those 3 models okay for the Hint I gave? This is
pretty confusing.
You don't need a Subcategory model/table, specially if they have the same columns. Your categories table should have a parent_id column. A category is a subcategory when it has a parent_id value pointing to another category record. Categories with a NULL parent_id are the top level categories.
Example
class Lawyer < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :lawyers
# This is called a self referential relation. This is where records in a
# table may point to other records in the same table.
has_many :sub_categories, class_name: "Category", foreign_key: :parent_id
# This is a scope to load the top level categories and eager-load their
# lawyers, subcategories, and the subcategories' lawyers too.
scope :top_level, -> { where(parent_id: nil).include :lawyers, sub_categories: :lawyers }
end
Note: you should create a migration to add the parent_id column to the categories table. And you can drop the subcategories table.
Now create some of your categories (I'm assuming there's a name column):
cat = Category.create name: "Corporate and Commercial Law"
subcat = Category.new name: "Corporate Tax", parent_id: cat.id
subcat.lawyers << Lawyer.find_by_name("Sabina Mexis")
subcat.save
Example table of contents:
<% Category.top_level.each do |cat| %>
<%= cat.name %>
<% cat.sub_categories.each do |subcat| %>
<%= subcat.name %>
<%= subcat.lawyers.each do |laywer| %>
<%= lawyer.name %>
<% end %>
<% end %>
<% end %>
The above is a simplified example. Hope that helps.
Update
To enhance your form to allow you to create a subcategory and assign its parent category, use a select menu filled with top_level category IDs:
<%= form_for Category.new do |f| %>
<%= f.text_field :name %>
<%= f.select :parent_id, options_from_collection_for_select(Category.top_level, :id, :name) %>
<%= f.submit %>
<% end %>
Check out the docs for options_from_collection_for_select if it's unfamiliar. What it does is build a select menu with the category:id as values and their :name as the text in the menu. Make sure you add :parent_id to your strong parameters to allow mass assignment via params[:category].
The laywer error was just a typo in my example code, it's fixed now.

Selection of elements based on other elements

class Teacher < ActiveRecord::Base
has_many :students
end
class Class <ActiveRecord::Base
has_many :students
end
class Student <ActiveRecord::Base
belongs_to :teacher
belongs_to :class
end
I want to create a list of teachers, and below their names: table with classes from which this teacher has students and number of this students. More or less something like this:
Teacher XYZ:
Class 1A | 3 students
Class 3D | 2 students
How can I check if teacher has students from each class and later count only the students that belongs to both this particular teacher and class?
You can do a query to eager load the classes and students:
#teachers = Teacher.includes(students: :class)
Then I would use group_by in the view to group the students by the class.
<% #teachers.each do |teacher| %>
<%= teacher.name %>
<% teacher.students.group_by(&:class).each do |class, students| %>
<%= class.name %> | <%= students.size %>
<% end %>
<% end %>
I've assumed that a teacher and a class both have a name. There may well be a better way using something like has_many through but I can't see it at the moment.
On another note you shouldn't name your object Class it's going to cause you a lot of problems I'd have thought because it's defined in ruby already http://ruby-doc.org//core-2.2.0/Class.html. I'd call it something like SchoolClass to avoid conflicts.

Create/Edit middle model class in many-to-many relationship

Currently, my app have 3 models,
I want to add new Receipt by specifying the quantity of food required.
class Receipt < ActiveRecord::Base
# columns: id, place
has_many :receipt_foods
has_many :foods, through: :receipt_food
end
class ReceiptFood < ActiveRecord::Base
# columns: id, quantity, receipt_id, food_id
belongs_to :receipt
belongs_to :food
end
class Food < ActiveRecord::Base
# columns: id, name
has_many :receipt_foods
has_many :receipts, through: :receipt_food
end
My problem is how to create the quantity of food in my form,
for example: create 3 different food where 3 quantity each food
I know how to create this in rails console only, don't know how in web using form_for
I have try fields_for but most examples explain create and edit 2 models property only.
Can any one suggest ways or any materials/articles talk about this?
Thanks
I am not sure, but I would do:
= form_for :receipt_food do |f|
= f.number_field :quantity, min: 0
= f.select :food_id, Food.all.map{ |food| [food.name, food.id] }
= f.select :receipt_id, Receipt.all.map{ |receipt| [receipt.place, receipt.id] }
I would add labels to these fields.
Also, I think the convention is to name it: FoodReceipt, it's alphabetical.

How do you query upstream in a polymorphic association without raw SQL?

In my exercise app, users can "check" an exercise to complete it. If I know that checkable_type is 'Exercise' and have the checkable_id, how do I query the exercise name?
I'm not sure what to put in my controller to have a list of "completed exercises" and their names based on checkable_type and id.
class Exercise < ActiveRecord::Base
attr_accessible :name
has_many :checks, :as => :checkable
end
class Check < ActiveRecord::Base
belongs_to :checkable, :polymorphic => true
attr_accessible :checkable, :checkable_id, :checkable_type
end
Would just joining the other model give you what you wanted?
completed_exercises = Exercise.joins(:checks)
That should produce an inner join, and AR already knows how to include the polymorphic association as part of the query.
You can define a scope checkable_type
scope :checkable_type, lambda { |class_name| where("checkable_type = ?", class_name) }
I guess you want the polymorphic records with type 'Exercise' and that would be created only when exercises are completed or you can maintain it in a completed_at timestamp column for that matter.
Then you can pulls a list of all completed exercises
scope :completed, where('completed_at IS NOT NULL')
completed_exercises = Check.checkable_type('Exercise').completed
You may ignore the completed scope if that's not the case
Figured it out!
class Exercise < ActiveRecord::Base
attr_accessible :exercise_name
has_many :checks, as: :checkable
end
class Check < ActiveRecord::Base
belongs_to :checkable, polymorphic: true
attr_accessible :checkable_id, :checkable_type, :exercise_name
end
I realized I needed to call .checkable before calling the desired attributes in the exercise model.
<% #checks.each do |check| %>
<%= check.checkable.exercise_name %>
<%= check.checkable.created_at %>
<% end %>
This pulls the right exercise name and "completion time" (via created_at) from the exercise table.

Ruby on Rails collection_select complexity

i have the following Problem, i Have the following in my customer bill view
<%= f.collection_select :product_id,Product.all,:id,:name %>
This is getting list of all the products from "Product" model and giving option to select from it. But i want to select the list of products from the "StoreOpeningStock" model.
I have these in my model
class Product< ActiveRecord::Base
has_many :store_opening_stocks
has_many :customer_bills
attr_accessible :name
end
class StoreOpeningStock < ActiveRecord::Base
attr_accessible :product_id
belongs_to :product
end
class CustomerBill < ActiveRecord::Base
attr_accessible :product_id
belongs_to :product
accepts_nested_attributes_for :store_opening_stock
end
Can anyone guide me how i can get product name and id from store_opening_stock??? Should i use Helpers??? or is there any other way?? Thanks in advance
I tried using helpers
def getting_prod_names
#sto = StoreOpeningStock.all
for x in #sto
[
['{x.product.title}', '{x.product_id}']
]
end
end
getting following output
<%= f.select :product_id, options_for_select(getting_prod_names) %>
ANy Help?? :)
When you create a form the data used to ccreate a collection_select isnt limited to the Class your going to create an object for. You could simply do the following:
<%= f.collection_select :product_id,StoreOpeningStock.all,:product_id ,:name %>
This should to it for you,...
add this to your StoreOpeningStock class:
def name
return self.product.name unless self.product.nil?
""
end
You need to clarify the relationship between your models...
But just to give you an idea. You can define the collection of products you want to display in your controller, inside the action related to the view (where you are displaying the collection).
Controller:
#products= #here you should call all products you want
Then, your collection of products can be displayed like:
<%= f.collection_select :product_id, #products,:id,:name %>
EDIT
You need to revise the relationship between your models. A product has many customer_bills, but are you sure that each customer_bill belongs to a single product?
I think you have a many-to-many relationship, as a customer_bill can also have many products.
If I understand it right, the solution is to create a ProductLine model between this many-to-many relationship.
Also, what is the difference between Product and StoreOpeningStock? What attributes have you included in the StoreOpeningStock?
If you have created this model only to show the availability of products, why don't you add an attribute in the Product model, for example a boolean column called availability.
So you want to find all products that have a StoreOpeningStock.
This is solely a model concern and have nothing to do with helpers.
class Product
# Find all products that have a StoreOpeningStock
def self.in_stock
find(StoreOpeningStock.product_ids)
end
end
class StoreOpeningStock
# Collect all product ids from stocks
def self.product_ids
uniq.pluck(:product_id)
end
end
Now you can use Product.in_stock instead of Product.all to have the only ones in stock.
I'd add a scope to your products model:
class Product< ActiveRecord::Base
has_many :store_opening_stocks
has_many :customer_bills
attr_accessible :name
scope :having_store_opening_stocks, :joins => : store_opening_stocks, :select => 'distinct product.*', :conditions => 'store_opening_stocks.product > 0'
end
Then you can use Product.all.having_store_opening_stocks to select only products with such stocks, for example:
<%= f.select :product_id, Product.having_store_opening_stocks.map { |product| [product.name, product.id] } %>

Resources