My application consists of a drink model
class Drink < ActiveRecord::Base
attr_accessible :name
has_many :recipe_steps, :dependent => :destroy
has_many :ingredients, through: :recipe_steps
end
An ingredient model
class Ingredient < ActiveRecord::Base
attr_accessible :name
has_many :recipe_steps
end
how would I go about having it so when a user searches an ingredient that it returns all of the drinks with that ingredient?
Additional information: I'm currently using sunspot/solr for my searching.
First, in your Ingredient model you'd need this line:
has_many :drinks, through: :recipe_steps
To define the has_many, through: relationship. Make sure that RecipeStep has these lines, too:
belongs_to :ingredient
belongs_to :drink
Then you can do something like in the DrinksController:
def search
term = params[:search]
ingredient = Ingredient.where(:name => term)
#drinks = Ingredient.find(ingredient).drinks
end
And your form should look something like this:
<%= form_for #drink, :url => { :action => "search" } do |f| %>
<%= f.text_field :search %>
<% end %>
I don't know all your names for everything but this should get you going.
Following should work fine:
class Ingredient < ActiveRecord::Base
...
has_many :recipe_steps
has_many :drinks, through: :recipe_steps
end
Related
These are my models:
Product.rb:
class Product < ApplicationRecord
belongs_to :position
has_many :products_sizes
has_many :sizes, through: :products_sizes
has_many :reviews, dependent: :destroy
accepts_nested_attributes_for :products_sizes
end
Products_size.rb:
class ProductsSize < ApplicationRecord
belongs_to :product
belongs_to :size
has_many :prices
accepts_nested_attributes_for :prices
end
Size.rb:
class Size < ApplicationRecord
has_many :products_sizes
has_many :products, through: :products_sizes
end
and Price.rb:
class Price < ApplicationRecord
belongs_to :products_size
end
In ActiveAdmin I need to make a form for Product, for when I update the product, I could create a Price, so a part of the form looks like this:
... #here is the begining of the form
f.inputs 'Sizes' do
f.semantic_fields_for ProductsSize.where(product_id: params[:id], size_id: Product.find(params[:id]).products_sizes.size.to_i).first.prices.new do |ps|
ps.input :products_size_id, label: 'Size', as: :select, collection: Product.find(params[:id]).sizes.map { |s| ["#{s.title}", s.id] }
ps.input :quantity
ps.input :amount
li do
link_to 'Add size', '#'
end
end
end
It's all seems to be good, except when clicking the submit button, the Price isn't created. I think, that's because the permit_params are not specified for price. How can I specify them? Thanks.
ActiveAdmin.register Post do
permit_params :title,
comments_attributes: [:name, :hidden]
end
Post is a moodel and comments is another. You can use params from comments with comments_attributes, if your model name is price you can use price_attributes: [...params...].
Here is how you allow parameters in active admin
ActiveAdmin.register Post do
permit_params :title, :content, :author
end
This is just an example, use your own params
I would like to select in simple_form <%= f.association :organisators, collection: User.all %> and <%= f.association :helpers, collection: User.all %> that source of them will be User ids stored in Participation join table with appropriate enum kind, is it a way to do it automatically with ActiveRecord relations?
class Participation < ActiveRecord::Base
belongs_to :user
belongs_to :event
enum kind: [:helper, :organisator]
end
class Event < ActiveRecord::Base
belongs_to :user
has_many :participations
has_many :organisators, class_name: 'Participation'
has_many :helpers, class_name: 'Participation'
end
class User < ActiveRecord::Base
has_many :events
has_many :participations
end
When I try to save current version then it raise: Couldn't find Participation with 'id'=1
event_params: {"helper_ids"=>["2"], "organisator_ids"=>["1"]}
I would recommend using Single Table Inheritance over an enum. Keep the existing Participation model, and create two other models (helper and organiser) which will inherit from it.
Once you have implemented this, you can have two different object types which can be referenced through relationships while sharing one database model.
Take a look at this documentation:
http://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html
source of them will be User ids stored in Participation join table
You need to pull from the Participation model, not the User model:
class Participation < ActiveRecord::Base
belongs_to :user
belongs_to :event
enum kind: [:helper, :organisator]
end
class Event < ActiveRecord::Base
belongs_to :user
has_many :participations
has_many :organisators, -> { where kind: :organisator}, class_name: 'User', through: :participations, source: :user
has_many :helpers, -> { where kind: :helper}, class_name: "User", through: :participations, source: :user
end
class User < ActiveRecord::Base
has_many :events
has_many :participations
has_many :participated_events, through: :participations
end
You've basically got a has_many :through relationship.
--
Thus, you should be able to use:
#app/views/events/update.html.erb
<%= simple_form_for #event do |f| %>
<%= f.association :organisators, collection: #event.organisators %>
<%= f.association :helpers, collection: #event.helpers %>
<%= f,submit %>
<% end %>
It would help if you gave some context on what you're trying to achieve. The above code should help, we may have to tweak it a little.
I have five models: Course, Lesson, Question, Answer and User.
What I'm trying to do is determine if the User has Answers for all of the Questions in a Lesson (so I can put "Done" next to the lesson in the view if this is the case).
My models:
class Course < ActiveRecord::Base
has_many :lessons, dependent: :destroy
has_many :questions, :through => :lessons
has_many :users, through: :purchases
end
class Lesson < ActiveRecord::Base
belongs_to :course
has_many :questions, dependent: :destroy
has_many :answers, through: :questions
end
class Question < ActiveRecord::Base
belongs_to :lesson
belongs_to :course
has_many :answers, dependent: :destroy
end
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
class User < ActiveRecord::Base
has_many :answers
has_one :author
has_many :courses, through: :purchases
end
What I tried to do was to check if a Lesson's Questions were in the Questions the User Answered, but the includes? line doesn't seem to be working the way I want.
in my controller, I have:
#lessons = #course.lessons
#answers = current_user.answers
#questions = Question.where(:id => #answers.map(&:question_id))
in my view, I have:
<% #lessons.each do |lesson| %>
<% lesson_questions = lesson.questions %>
<%= user_questions = #questions.where("lesson_id = ?", lesson.id)%>
<% if user_questions.include?(lesson_questions)%>
Done!
<% end %>
<% end %>
I'm not sure if this is the cause, but I noticed the lesson_questions are #<Question::ActiveRecord_Associations_CollectionProxy:0x9c49698>
While the user_questions are: #<Question::ActiveRecord_Relation:0x9c48330>
I'm wondering, (a) how I accomplish my objective of finding the Lessons with all of the Questions answered, and (b) if there's a more efficient way to do this. Thanks!
Problem
You can't check if an array includes another array just like this:
user_questions.include?(lesson_questions)
You need to check if each element from lesson_questions is included in the user_questions.
Try these instead:
Solution: 1
lesson_questions.all? { |lq| user_questions.include?(lq) }
This should return true if all the lesson_questions are included in the user_questions.
Solution: 2
(lesson_questions - user_questions).empty?
I have Aulas and Students Through Grades,
in grades I want to display the name of the student and the name of the Aula.
<% #grades.each do |grade| %>
<%= grade.student.name %>
<%= grade.aula.name %>
<% end %>
If I leave only the student I get it perfect, But when I want to get Aula name, I get:
undefined method `aula' for #<#<Class:0x30a37e8>:0x2fffeb0>
Here is my code
class Aula < ActiveRecord::Base
attr_accessible :name
has_many :grades
has_many :students, :through => :grades
end
class Student < ActiveRecord::Base
attr_accessible :name
has_many :grades
has_many :aulas, :through => :grades
end
class Grade < ActiveRecord::Base
attr_accessible :grammar, :oral, :participation, :writing
belongs_to :aula
belongs_to :student
end
I figure that the problem is that if grade.aula.name is nil, I get this error. If the data is there, it works perfectly.
How can I do an action like, if grade.aula.name.nill? grade.aula.name = 'write the name here'?
I have such terrible models:
class ParentalRelation < ActiveRecord::Base
belongs_to :parent
belongs_to :student
belongs_to :counselor
belongs_to :parental_relation_type
end
class ParentalRelationType < ActiveRecord::Base
has_many :parental_relations
end
class Parent < ActiveRecord::Base
has_many :parental_relations
has_many :students, :through => :parental_relations
has_many :counselors, :through=> :parental_relations
has_many :parental_relation_types, :through=> :parental_relations
belongs_to :user, :dependent=> :destroy
belongs_to :occupation_type
accepts_nested_attributes_for :user
end
Parental relation types are like father, mother, etc. The reasoning is that a parental relation between one counselor, one parent and one student is unique and counselors should not see the relations that belong other counselors.
In controllers/parent_controller/edit action I have:
#parental_relation= ParentalRelation.find_by_counselor_id_and_student_id_and_parent_id(x, y, z)
In views/parent/_form.html.erb I have:
<%= form_for #parent do |f| %>
inside that form I need a collection_select for ParentalRelationType.all and select the parent's parental_relation_type_id for that particular parental relation, but I can't find the syntax to do it.
I tried adding
<%= collection_select(#parental_relation, :parental_relation_type_id, ParentalRelationType.all, :id, :name) %>
underneath the form_for, but the relation type id is 2, and default 1 is selected instead.
Added this to parents/_form
<%= fields_for #counselor_student_parent do |csp| %>
<%= f.label :parental_relation_type_id %>
<%= collection_select(:student_counselor_parent, :parental_relation_type_id, ParentalRelationType.all, :id, :name) %>
<% end %>
And this to parents_controller/new
def new
#counselor= Counselor.find(params[:counselor_id])
#student= Student.find(params[:student_id])
#parent= #student.parents.build
#parent_user= #parent.build_user
#counselor_student_parent= #counselor.student_counselor_parents.build
end