Rails joining tables having has_many association - mysql

I have Student and Record table with a simple has_many :through association:
class Student < ActiveRecord::Base
has_many :records
end
I need to fetch all students details of MBA branch. I need to assign result to a variable #students and need to access record of a student using
#students.each do |student|
students.records.each do |record|
///
end
end
That is I need to access has_many related class datas also into an object. How to write query for that. I am newbee in rails. Please help .Thanks in advance

try this,
#student = Student.where("student.course = ?", "MBA").includes(:records)
Then do eaching on instance variable. This will save you from N+1 issue

It looks like you have a has_many relation instead of has_many :through. Have you looked through the rails guides? There they describe how to fetch data from the database. http://guides.rubyonrails.org/active_record_basics.html#read
Here is a more detailed reference on the has_many relation: http://guides.rubyonrails.org/association_basics.html#has-many-association-reference
Make sure you access student and not students in the loop.
#students.each do |student|
student.records.each do |record|
///
end
end
Where is the MBA branch coming from? Is that another table?
You probably will end up with something like #students = Student.where(branch_id: 1).
The ID 1 is just fictional but I'm guessing you have your branches in another table.

Related

Elixir Ecto: Using a Pivot Attribute in a Many To Many Relationship

I am currently having troubles figuring out how to use pivot attributes in an Ecto many-to-many relationship.
I found the following question but unfortunately nobody had an answer: https://stackoverflow.com/questions/37158184/elixir-ecto-pivot-many-to-many-table-attributes
Basically I need the same setup as mentioned in the question. Two models and I need to store data to the pivot entry.
Has anybody a solution for this problem?
Thanks in advance!
I am doing something like the following in one of my applications
def Foo do
schema "foos" do
field :name, :string
has_many :bars_foos
end
end
def Bar do
schema "bars" do
field :other, :integer
has_many :bars_foos
end
end
def BarFoo do
schema "bars_foos" do
field :size, :integer
belongs_to :bars
belongs_to :foos
end
end
This uses has_many and belongs_to instead of many_to_many, but it accomplishes something very similar. You can also still use the many_to_many with through if you need a direct link to the other dataset.

Using form to update has_many through join table

I am short of implementation ideas for my rails project. at this point it seems impossible to implement in rails.
I am cloning a sort of accounting software into a web app using rails framework for small manufacturing companies to keep track of their products stock in their different distribution branches.
I have 3 different models: "Product", "Branch" & "Accumulator"
class Branch < ActiveRecord::Base
has_many :accumulators
has_many :products, :through => :accumulators
end
class Product < ActiveRecord::Base
has_many :accumulators
has_many :branches, :through => :accumulators
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
end
end
class Accumulator < ActiveRecord::Base
belongs_to :product
belongs_to :branch
end
I am new to rails and after reading up on many to many associations I came across using collections to add products to a branch "#branch.products << Product.all"
Is there a possible way to use a form "number_field_tag" in the branch show view to add multiple of specific products into the join table?
eg
I want to add 10 of (Product) called "garden eggs" to a (Branch) called "lagos branch" to the (Accumulator) join table using a form in Branches show view?
Congratulations for choosing :has_many, through: you will not regret it.
Is the relationship between a product and a branch static?
Or does it change a lot?
In your Accumulator model, add an integer field called amount (count can have conflicts). Then you either create a form for your Accumulators or you add a nested form with for example Cocoon.
This way you can add Accumulators to your Branch with a certain Product and a certain amount.
Off topic:
Here is an article about why has_many through has some advantages:
http://blog.flatironschool.com/why-you-dont-need-has-and-belongs-to-many/
If you have problems with forms I can really recommend SimpleForm and for nice Javascript-assisted fields I recommend Select2.
If the table accumulators needs to save only two things: product_id, and branch_id, you can easily use has_and_belongs_to_many associations.
class Branch < ActiveRecord::Base
has_and_belongs_to_many :products, join_table: 'accumulators'
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :branches, join_table: 'accumulators'
end
And now, there is no need for the third model.
As far as it goes, how to add a relationship, it's pretty easy in this case:
branch = Branch.last
branch.products << Product.create # you don't need to touch the middle table.
Instead of using number_field_tag to ask for plain ids, you can use something fancy like jQuery Chosen Plugin. This plugin will allow you to use tag like input, and will send the ids to the server separated by ,'s.

Rails query on different models in a multi-level association chain

I have a multi-level model structure, and I am trying to create a query where I can search for either an attribute on the main parent model, or the last model in the associatioon change. My structure looks like the following:
class Parent
attr_accessible :pname
has_one :child
end
class Child
has_many :infos
end
class Info
has_one :setting
end
class Setting
has_many :subsettings
end
class Subsetting
attr_accessible :sname
end
What I am trying to do is create a where query, where i can pull all parents where either the "pname = X" or "sname = X". However, I am unsure of how to create the associations that deep: Is there a way I can do it cleanly using active record, or is it better to create a mysql query directly?
I'm typing this freehand, so it's possible this won't be 100%, but you should be able to do something like the following...
class Parent
has_one :child
has_many :infos, through: :child
has_many :settings, through: infos
has_many :subsettings, through: :settings
...
end
Then you should be able to call...
Parent.joins(:subsettings).where("parent.pname = ? OR subsetting.sname =?", x)
Two things to note about the .where() call:
Because you are querying against multiple joined tables, you need to preface the column with the table name.
The table name is singular, not plural. That's why subsetting and not subsettings.

Unable to make sense of database data in Rails console

I'm trying to gather a set of data for current_user so in my controller code I have:
#user_workouts = current_user.planned_workouts
with planned_workouts being the join table b/w the user and the workouts. When I test that in console:
#user_workouts.count
I get 4.
When I do:
PlannedWorkout.count
I get 4.
But when I try using a .each loop for my #user_workouts:
#user_workouts.each do |user_workout|
puts user_workout
end
I get far more than 4, I get something like ~25, how is that possible when I tested above how many planned_workouts there are in the table and for the user themselves? I also tried deleting all of the planned_workouts so that the table is empty and created 4 new ones, and still the same outcome. Can it have anything to do with the fact that I'm using add_index in the schema?
EDIT:
My model associations:
User.rb
has_many :planned_workouts
has_many :workouts, through: :planned_workouts
Workout.rb
has_many :planned_workouts
has_many :users, through: :planned_workouts
PlannedWorkout.rb
belongs_to :workout
belongs_to :user

complicated search design

I am implementing a recipe search on rails3 using mysql.
The idea of search is that user enters any number of ingredients and search outputs suggestions what to make, sorted in product deficiency order.
class Recipe < ActiveRecord::Base
has_many :ingredients
end
# these records will be entered by user
class IngredientType < ActiveRecord::Base
has_many :ingredients
end
# this table is join table
class Ingredient < ActiveRecord::Base
belongs_to :ingredient_type
belongs_to :recipe
end
What would be the most efficient way to implement this search?
What gems or techniques would you recommend?
Thank you for your answers
def self.from_ingredients ingredients
count_sql = Ingredient.
select('COUNT(*)').
joins(:recipes_ingredients).
where('`recipes_ingredients`.`recipe_id` = `recipes`.`id`').
where('`ingredients`.`id` in (?)', ingredients).to_sql
where("(#{count_sql}) > 0").
order("((`recipes`.`ingredients_count`) - (#{count_sql})) ASC")
end
I managed to find solution by creating such method in recipe model.