what i want to accomplish it's almost exactly the same as this!
railscast tutorial but can't get it to work.I have a courses table and a enrollments table they have a many to many relation so i have a join table called "courses_enrollments" i'd like to be able to add many courses to enrollments all at once from a form... i used a has_many_through relation and looped through all the courses in the form and for each of them i have a checkbox so i can add them to enrollments but when i save nothing happens my join table (courses_enrollments) never gets filled with the relations i want.... here are my models:
courses:
class Course < ActiveRecord::Base
has_many :courses_enrollments
has_many :enrollments, :through => :courses_enrollments
enrollments:
class Enrollment < ActiveRecord::Base
has_many :courses_enrollments
has_many :courses, :through => :courses_enrollments
and courses_enrollments:
class CoursesEnrollment < ActiveRecord::Base
belongs_to :courses
belongs_to :enrollments
end
and finally my enrollments form view:
<%= form_for(#enrollment) do |f| %>
<% if #enrollment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#enrollment.errors.count, "error") %> prohibited this enrollment from being saved:</h2>
<ul>
<% #enrollment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :state %><br>
<%= f.collection_select(:state, Courses.all, :id, :name, {:include_blank => true}, {:multiple => false}) %>
</div>
I also tried it like this in the form.... but nothing gets saved here either
<% Courses.all.each do |course|%>
<%= check_box_tag "enrollment[course_id][]", course.id %>
<%= course.name %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
i want to be able to save many records to the join table that holds the relation between the enrollments i am creating or updating and the courses i selected with the has many through association.... appreciate the help
Models:
class Course < ActiveRecord::Base
has_and_belongs_to_many :enrollments
class Enrollment < ActiveRecord::Base
has_and_belongs_to_many :courses
with this type of association you end up with a join table which will have course_id and enrollment_id . Thus not needing to create a new model just to handle your association. Rails already does that for you.
After that, in your controllers, make sure the accepted_params have this:
Controllers:
def course_params
params.require(:course).permit(
...
enrollments_ids: []
def enrollment_params
params.require(:enrollment).permit(
...
courses_ids: []
Related
Still learning rails and have been stuck on this for a while, I have a feeling it's a simple fix and I'm just not getting it.
I'm trying to use a separate model to populate a dropdown in another model's form. So a nested form. It is the type of activity done in a workout.
Here's what I have set up.
Workout Model
class Workout < ActiveRecord::Base
belongs_to :user
has_many :activities
accepts_nested_attributes_for :activities
validates :activity, presence: true
end
Workout Controller Params
def workout_params
params.require(:workout).permit(:rating, :activity, :workout_date, :activity_id, activity_params:[:id, :title])
end
Activity Model
class Activity < ActiveRecord::Base
belongs_to :workout
end
Activity Controller Params
def activity_params
params.require(:activities).permit(:title, :rating, workout_params:[:id])
end
View
<%= form_for(#workout) do |f| %>
<div class="control-group">
<%= f. label :activity, class: 'control-label' %>
</div>
<div class="checkbox">
<%= collection_select( :activity, :workout_id, Activity.all, :id, :title, {},
{:multiple => false }) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Thanks in advance
Fixed it. Error was in the view > collection_select. The order was wrong and i changed :activity_id to :activity
<%= collection_select :workout, :activity, Activity.all, :id, :title, {}, {:multiple => false } %>
I have a model called timesheet. i wanted to have a nested form for this timesheet model. means i do not want to add any child models to it. Basically i want to have nested form for single model(timesheet).
when i click add button another form should come to the parent model(timesheet) similarly when we click remove the form should be removed. how can i do this? is there any gem to do this ?
i am using the self referential association.
getting the error:Invalid association. Make sure that accepts_nested_attributes_for is used for :log_times association.
<%= nested_form_for(#log_time, html: {:class => 'form-inline'}) do |f| %>
<%= f.label :date %>
<%= f.date_select :date, { order: [:day, :month, :year] } ,{:class => 'form-control' } %>
<%= f.fields_for :log_time do |details| %>
<%= details.label :date %>
<%= details.date_select :date, { order: [:day, :month, :year] } ,{:class => 'form-control' } %>
<%= details.link_to_remove "<i class='fa fa-minus'></i>Remove".html_safe,:class=>"btn btn-danger btn-sm" ,:style=>"color: white;"%>
<%end %>
<%= f.link_to_add "<i class='fa fa-plus'></i>Add".html_safe, :log_times, :class=>"btn btn-primary btn-sm", :id=>"",:style=>"" %>
<%= f.button "Submit" ,:class=>"btn btn-primary btn-sm" do%>
<i class='fa fa-send-o'></i>Submit
<%end%>
<% end %>
Add a self-referential association to your timesheet model:
class Timesheet < ActiveRecord::Base
belongs_to :parent, class_name: 'Timesheet'
has_many :children, class_name: 'Timesheet', foreign_key: 'parent_id'
accepts_nested_attributes_for :children
end
In the controller you can do:
#timesheet = Timesheet.new
#timesheet.children.build
I'm attempting to create a new oil production within the production information page. The fields are appearing but I am unable to get the oil production to save. Any help is appreciated
Productioninfos_controller.rb
def index
#productioninfos = Productioninfo.all
end
def new
#productioninfo = Productioninfo.new
end
def productioninfo_params
params.require(:productioninfo).permit(:firstproduction, :lastproduction, :numberofcompl, :totaldepth, :productionzone, oilproductioninfos_attributes: [:id, :oilcum, :avgbpmlastsixmonths, :avgbpodlastsixmonths])
end
Productioninfo.rb (model)
has_many :oilproductioninfos
accepts_nested_attributes_for :oilproductioninfo, :allow_destroy => :true, :reject_if => :blank
Oilproductioninfo.rb (model)
belongs_to :productioninfo
Productioninfos_form.html.erb
<%= f.fields_for :oilproductioninfos do |ff| %>
<div>
<%= ff.label :oilcum %>
<%= ff.text_field :oilcum %>
<%= ff.label :avgbpmlastsixmonths %>
<%= ff.text_field :avgbpmlastsixmonths %>
<%= ff.label :avgbpodlastsixmonths %>
<%= ff.text_field :avgbpodlastsixmonths %>
</div>
I am trying to incorporate Simple_forms into my app using a virtual attributes. I am following http://railscasts.com/episodes/102-auto-complete-association-revised to get autocomplete to work as well. Simple_form works when i do not use a virtual attribute but when I do use the virtual attribute I get the error "Association :head_coach_name not found".
My Team Model is:
class Team < ActiveRecord::Base
attr_accessor :head_coach_name
belongs_to :user
validates :team_name, presence: true
belongs_to :head_coach, class_name: "User", :foreign_key => "head_coach_id"
def head_coach_name
user.try(:name)
end
def head_coach_name=(name)
self.user = User.find_by_name(name) if name.present?
end
end
My User model is:
class User < ActiveRecord::Base
has_many :teams, :class_name => "::Team", dependent: :destroy
end
My View:
<%= simple_form_for #team, html: {class: 'form-horizontal' }, url: teams_path, method: 'post' do |f| %>
<%= f.error_notification %>
<%= f.hidden_field :user_id %>
<div class="col-md-6">
<div class="row">
<div class="col-md-12">
<%= f.input :team_name, class: "form-control" %>
<%= f.input :year, collection: Date.today.year-90..Date.today.year %>
<%= f.input :season, as: :select, collection:
['Fall',
'Winter',
'Spring',
'Summer'] %>
<%= f.input :season_type, as: :select, collection:
['Outdoor',
'Indoor',
'Tournament'] %>
<%= f.input :awards %>
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-12">
<%= f.input :club %>
<%= f.input :division %>
<%= f.association :head_coach_name %>
<%= f.input :assistant_coach_id %>
<%= f.input :assistant_coach_two_id %>
</div>
</div>
</div>
<%= f.button :submit, label: "Add team", class: "btn btn-large btn-primary col-md-3 pull-right" %>
<% end %>
Everything works as long as i don't have the virtual association in there. I could put :head_coach and it would work with a drop down list but I want to use the autocomplete feature like in the railscast video. Also in rails console i can run these commands to show the virtual attribute works:
2.1.2 :003 > team.head_coach_name
User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 100 LIMIT 1
=> "Miss Daisha Shanahan"
Any ideas on how I can get the virtual attribute to work correctly with simple_forms?
You are referencing an association that doesn't exist with f.association :head_coach_name. Try this instead:
f.association :head_coach, label_method: :head_coach_name
You have a few other oddities in your code, including your head_coach_name definition, which should rely on head_coach instead of user. Same concern for the head_coach_name= method.
Example. You have:
def head_coach_name
user.try(:name)
end
Seems like you should have:
def head_coach_name
head_coach.try(:name)
end
I still novice with RoR. My mission is to add examplaries according to the number of exemplary inserted in the form of book, knowing that i have a book table and an examplary table and the relationship in between is a book has_many exemplaries and an exemplary belong_to a book.
This is my attempt:
in books_controller.rb
method create:
def create
#book= Book.new(book_params)
if #book.save
#book.nbr_exemplaires.times do |i|
#exemplaire= Exemplaire.create(book_id: #book.id, state: 0 )
end
flash[:notice]='goood'
redirect_to admin_manage_path
else
flash[:alert]='ouups'
redirect_to root_url
end
end
private
def book_params
params.require(:book).permit(:title, :pages, :resume,:nbr_exemplaires, :has_exemplaires, :author_ids =>[], :subject_ids =>[])
end
book/new.html.erb:
<h1>Add new book</h1>
<%= form_for(#book) do |form| %>
<div> <%= form.label :title %><br>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :pages %><br>
<%= form.number_field :pages %>
</div>
<div>
<%= form.label :resume %><br>
<%= form.text_area :resume %>
</div>
<div>
<p>select author from existing list</p><br>
<%= form.collection_select :author_ids, #authors, :id, :l_name, {:selected => 1}, {:name => 'book[author_ids][]'} %>
</div>
<div>
<p> Select subject from existing list</p><br>
<%= form.collection_select :subject_ids, #subjects, :id, :name, {:selected =>1}, {:name => 'book[subject_ids][]'} %>
</div>
<div>
<%= form.label :has_exemplaires? %>
<%= form.check_box :has_exemplaires,{}, 'Yes', 'No'%>
<div id="expl_details" style="display:none;">
<%= form.label :nbr_exemplaires %> <%= form.number_field :nbr_exemplaires %>
</div>
</div>
<%= form.submit "Submit" %>
<% end %>
<script type="text/javascript">
var checkbox = document.getElementById('book_has_exemplaires');
var details_div = document.getElementById('expl_details');
checkbox.onchange = function() {
if(this.checked) {
details_div.style['display'] = 'block';
} else {
details_div.style['display'] = 'none';
}
};
</script>
Then I would suggest something like this:
class Book < ActiveRecord::Base
has_many :exemplaires
attr_accessor :nbr_exemplaires
after_save :create_exemplaires
private
def create_exemplaires
nbr_exemplaires.times do
self.exemplaires.create()
end
end
If you actually have a column name 'nbr_exemplaires' in your table, you don't need the attr_accessor line. That is only if you won't be saving that as separate value in the DB.
I would use nested attributes, that way rails will create them automatically for you through the same form:
class Book < ActiveRecord::Base
has_many :exemplaires
accepts_nested_attributes_for :exemplaires, allow_destroy: true
This would allow to use the nested form builder in your view:
<%= form_for(#book) do |form| %>
<div><%= form.label :title %><br>
<%= form.text_field :title %>
</div>
<%= form.fields_for :exemplaires do |f| %>
<%= f.text_field :name %>
... more fields
<% end %>
You could then add some javascript to create a multiple nested forms:
<%= link_to_add_fields "Add Exemplarie", f, :answers %>
With this kind of setup, rails will automatically create all the associated objects in the same action with no additional code on the controller/model side. Here is a great railscasts on it:
http://railscasts.com/episodes/196-nested-model-form-revised
If you haven't subscribed, I suggest you do. It's the most useful rails resource I ever used when starting out and it costs only a few $ a month. Good luck!