rails 3.1 has_many :through extra field in join model - ruby-on-rails

i'm trying to solve has_many :through association with additional text_field in join model.None of the existing answers do the trick for me.
I have three models:
class Partner
has_many :prices
has_many :services, :through => :prices
accept_nested_attributes_for :prices
end
class Service
has_many :prices
has_many :partners, :through => :prices
end
class Price
belongs_to :service
belongs_to :partner
end
Prices table looks like this:
id
partner_id
service_id
price
I need to enter price for every selected service.
View looks like this:
<%= form_for(#partner, :url => save_services_path(#partner.id), :remote => true) do |f| %>
<table>
<% #services.in_groups_of(4, false) do |services| %>
<tr>
<% services.each do |service| %>
<td>
<%= check_box_tag "partner[service_ids][]", service.id, #partner.services.include?(service) %>
<%= service.name %>
<%= f.fields_for :prices do |p| %>
<%= p.text_field :price %>
<% end %>
</td>
<% end %>
</tr>
<% end %>
</table>
<% end %>
Checkbox works fine, but i'm unable to update price for service.
I believe the problem is in nested form syntax...i've tried many different combinations but non worked.
Thanks in advance!
UPDATE:
controller action:
def save_services
#partner = Partner.find(params[:id])
#partner.update_attributes(params[:partner]
end
log:
Started PUT "/partners/save_services/337" for
Processing by PartnersController#save_services as JS
Parameters: {"utf8"=>"รข", "authenticity_token"=>"xxx", "partner"=>{"service_ids"=>["20", "24"]}, "commit"=>"Save", "id"=>"337"}

Why do you have this?
:url => save_services_path(#partner.id)
in your form_for? you're creating form with #partner, but saving with services.. try
<%= form_for(#partner, :url => {:action => 'update'}, :remote => true) do |f| %>
or post your params from log

Related

Creating a form based on a :has_many through relationship

I am new to ruby and I am trying to put together a form that will allow you to add items to an order. The form will need to take a quantity for each item in the order.
class Order < ActiveRecord::Base
belongs_to :restaurant
has_many :selections
has_many :items, :through =>:selections;
end
class Selection < ActiveRecord::Base
belongs_to :order
belongs_to :item
end
class Item < ActiveRecord::Base
belongs_to :menu
has_many :selections
has_many :orders, :through => :selections
end
class Restaurant < ActiveRecord::Base
has_many :orders
has_many :menus
has_many :items, :through => :menus
end
class Menu < ActiveRecord::Base
belongs_to :restaurant
has_many :items
end
order controller
# GET /orders/new
def new
#order = Order.new
#restaurant.items.all.each do |item|
#order.selections.build
end
end
orders/_form.html.erb :
The form is supposed to list out the available items and allow you to enter the quantity for an item.
<%= form_for [#restaurant,#order], :html => { :class => 'form-horizontal' } do |f| %>
<div class="control-group">
<%= f.label :current_table, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :current_table, :class => 'text_field' %>
</div>
</div>
<% f.fields_for :selections do |ff| %>
<div class="control-group">
<%= ff.label :quantity, :class => 'control-label' %>
<div class="controls">
<%= ff.text_field :quantity, :class => 'text_field' %>
</div>
</div>
<% end%>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
course_orders_path, :class => 'btn' %>
</div>
<% end %>
When I try to render the page I get the following error:
undefined method `quantity' for
<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Selection:0x007ffa0287cd60>
I realize this is probably because I haven't initialized any selections but I'm not entirely sure how/where I should do that. When the form is submitted I want to create an order with a selection for each of the non-empty quantities.
So my first question is how do I construct my form so that I can take a quantity for each item that I know about?
Do I need to initialize anything in the order controller to make this work?
Can you give me any advice or point me to a tutorial that shows me how to set up the create method of the order controller?
EDIT:
I added some code to the Order controller and the form, so when I render the page I no longer get an error, but none of my 'selection' fields rendered. I confirmed with some logging and the debugger that I correctly 'build' 4 selections so I would expect those form elements show up.
Any ideas would be appreciated.
Are you missing a
accepts_nested_attributes_for :nested_class
somewhere?
Also, I had to do something like
<%= form_for [#restaurant,#order] do |f| %>
...
<%= f.fields_for :selections, #order.selections do |ff| %>
...
<% end %>
...
<% end %>

accepts_nested_attributes with nested form and select field

Facing a issue in select tag with accepts_nested_attributes_for with has many and explicit foreign key. I am not able to get the associated values listed.
Models
class PlantPlate < Plate
has_many :unit_plates, :foreign_key => 'parent_id', :dependent => :destroy
accepts_nested_attributes_for :unit_plates, :allow_destroy => true
end
class UnitPlate < Plate
belongs_to :plant_plate, :foreign_key => 'parent_id'
end
View
/plant_plates/_form.html.erb
<%= nested_form_for([ :admin, #plant_plate ]) do |f| %>
<%= f.fields_for :unit_plates do |unit_plate| %>
<%= unit_plate.collection_select :parent_id, UnitPlate.all,:id,:name %>
<%end
<%end%>
I want to list all the associated unit plates in select tag . But somehow now able to do that with this select tag.
Thanks in advance
Try out form_for instead:
<%= form_for([:admin, #plant_plate]) do |f| %>
<%= f.fields_for :unit_plate do |unit_plate| %>
<%= unit_plate.collection_select :parent_id, UnitPlate.all, :id, :name %>
<% end %>
<% end %>
Try out using basic f.select:
<%= f.select :parent_id, options_from_collection_for_select(UnitPlate.all, 'id', 'name') %>

Rails 3, how to update habtm relation with single check_box_tag or Confirm-/Refuse-Buttons

I have a habtm model like:
class Recurrence < ActiveRecord::Base
has_many :participations, :include => :user
has_many :users, :through => :participations
accepts_nested_attributes_for :participations
attr_accessible :scheduled_to, :user_id, :user_ids
end
class Participation < ActiveRecord::Base
belongs_to :recurrence
belongs_to :user
attr_accessible :recurrence_id, :user_id
end
class User < ActiveRecord::Base
has_many :participations, :dependent => :delete_all
has_many :recurrences, :through => :participations
accepts_nested_attributes_for :participations
attr_accessible :name, :email, :phone, :recurrence_ids
end
with standard actions for the recurrences_controller (index, show, new, edit, create, update, destroy).
In the view of a single recurrence (/recurrences/10 -> show-action), I try to create/update the participation of user. When I do in the mentioned view something like:
<%= form_for #recurrence do |f| %>
<div class="checkbox">
<% for user in User.find(:all) %>
<div>
<%= check_box_tag "recurrence[user_ids][]", user.id, #recurrence.users.include?(user) %>
<%= user.name %>
</div>
<% end %>
</div>
<div class="actions">
<%= f.submit "Update", :class => 'btn btn-mini btn-primary' %>
</div>
<% end %>
erverything is working fine, I can add or remove the participation for one or more users.
BUT I like to do it - for just a single user, namely the current_user! I tried with the following source:
<%= form_for(#recurrence) do %>
<%= check_box_tag "recurrence[user_id]", current_user.id,
#recurrence.users.include?(current_user) %>
<%= current_user.name %>
<%= submit_tag "Update" %>
<% end %>
which is not working, more detailed
Updating the not changed status: not particpating, doesn't do anything: correct!
Changing status: from not participating - to participating, works for current_user, BUT will also delete the status of a other users: wrong!
Changing status: from participating - to not participating, won't change anything: wrong!
Any help is welcome!
Finaly I want to reduce the Check-Box to Confirm-/Refuse-Buttons with hidden-fields for the recurrence, but proabably there is easier rails-way?

How to add data from multiple models to same view (Rails 3.2)

Im trying to figure out how to have data from multiple models show up on the same calendar in my view. Right now it's showing birthdays, but i would love to add anniversaries & holidays as well (which are currently just lists in view).. *stripped unnecessary formatting for clarity
https://github.com/watu/table_builder
users/show.html.erb
<% if #user.friends.any? %>
<h3>Upcoming Birthdays</h3>
<div id="calendar">
<h2 id="month">
<%= link_to "<", :month => (#date.beginning_of_month-1).strftime("%Y-%m") %>
<%=h #date.strftime("%B %Y") %>
<%= link_to ">", :month => (#date.end_of_month+1).strftime("%Y-%m") %>
</h2>
<%= calendar_for #friends, :year => #date.year, :month => #date.month do |calendar| %>
<%= calendar.head('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun') %>
<%= calendar.day(:day_method => :dob) do |date, friends| %>
<%= date.day %>
<ul>
<% friends.each do |friend| %>
<li> <%= link_to h(friend.name), friends %><%= "\'s birthday"%></li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
<% end %>
<% if #user.holidays.any? %>
<h3>Upcoming Holidays</h3>
<% #user.holidays.each do |hld| %>
<td><%= hld.name %></td>
<td><%= hld.date %></td>
<% end %>
</tbody>
</table>
Models
class User < ActiveRecord::Base
has_many :friends
has_many :user_holidays
has_many :holidays, :through => :user_holidays
has_many :anniversaries
class Holiday < ActiveRecord::Base
attr_accessible :name, :date
has_many :user_holidays
has_many :users, :through => :user_holidays
end
class UserHoliday < ActiveRecord::Base
attr_accessible :holiday_id, :user_id
belongs_to :user
belongs_to :holiday
end
class Anniversary < ActiveRecord::Base
belongs_to :user
attr_accessible :anniversary_date, :spouse_name, :anniversaries, :interest_ids
has_many :person_interests, :as => :person
has_many :interests, :through => :person_interests
end
There's nothing about a view that keeps it from using data from other models. You just have to make sure that the controller action passes it to the view somehow. You're currently passing one #date object and one #user object; if you want other objects you should set those as well. I advise you to make those objects accessible via the #user object, which is to say that you should create instance methods for a User so that you can access them in a view
class User
def birthdays
...
end
def anniversaries
...
end
def holidays
...
end
end
And then in your view, you can simply call #user.birthdays etc, etc.

Collection_select within a nested model form

I have a Timesheet model, a Run model, and an Athlete model.
class Timesheet < ActiveRecord::Base
has_many :runs, :dependent => :destroy
accepts_nested_attributes_for :runs
end
class Run < ActiveRecord::Base
belongs_to :timesheet
belongs_to :athlete
end
class Athlete < ActiveRecord::Base
has_many :runs
end
Runs are nested under Timesheets, and I want to create a few runs on the same form I create a Timesheet, as shown in this railscast
class TimesheetsController < ApplicationController
def new
#timesheet = Timesheet.new
3.times { #timesheet.runs.build }
end
On my Timesheet form, I'm experiencing a problem with my collection_select (a drop down of Athlete names which populates the :athlete_id field in the Runs table).
<% form_for(#timesheet) do |f| %>
<%= f.error_messages %>
<%= f.label "Date" %>
<%= f.text_field :date %>
<% f.fields_for :runs do |builder| %>
<%= collection_select(:run, :athlete_id, Athlete.all(:order => 'name'), :id, :name, { :prompt => 'Select Athlete' } ) %>
<% end %>
<%= f.submit 'Create' %>
<% end %>
Is it possible to populate the :athlete_id field of a Run with a collection_select as shown above, within a nested form for Timesheet, or am I missing something?
It looks like you're not creating the collection select on the form builder, try something like this:
<% f.fields_for :runs do |r| %>
<%= r.collection_select(:athlete_id, Athlete.all(:order => 'name'), :id, :name, { :prompt => 'Select Athlete' } ) %>
<% end %>

Resources