Undefined method `customer_name' in nested association in Rails - ruby-on-rails

I'm pretty new in Rails and I need your help.
I have Job model, Invoice model and Item model.
job.rb model have - has_one :invoice, dependent: :destroy accepts_nested_attributes_for :invoice
invoice.rb have - belongs_to :job, optional: true, :foreign_key => 'job_id' has_many :items, dependent: :destroy accepts_nested_attributes_for :items
item.rb have - belongs_to :invoice, optional: true, :foreign_key => 'invoice_id'
Everything is ok, it creating the job and invoice with items inside and on invoice show it generate the invoice but in invoices/index I want to list all invoices in a table but I can't get = #invoice.job.customer_name.capitalize it give me a error - NoMethodError in Invoices#index undefined method `customer_name' for nil:NilClass.
It is like job is nil. My question is why in invoices/show.html.erb I can access
= #invoice.job.customer_name.capitalize and in index it give me error ?
As you can see in invoices/show.html.haml I have = #invoice.job.customer_name.capitalize and it give me correct data:
.container.invoice
.row
.col-sm-6
- if current_user.logo.present?
= image_tag current_user.logo.url(:thumb)
- else
= image_tag 'blank.jpg'
.col-sm-3
.col-sm-3
%h3
= current_user.full_name.titleize
%p
= current_user.email
%p
= current_user.phone
%hr
.row
.col-sm-6
%h4
Customer :
= #invoice.job.customer_name.capitalize.html_safe
%p
%b
Phone:
= #invoice.job.customer_tel
%p
%b
Email:
= #invoice.job.customer_email
.col-sm-3
.col-sm-3
%p
%b
Invoice: #
= #invoice.id
%p
%b
Date:
= #invoice.created_at.strftime("%B %d, %Y")
%hr
.row
.col-sm-12
%table.table.table-striped.table-hover
%thead
%tr.sortable-table
%th.col-sm-1
Item Id
%th.col-sm-3
Item/Operation
%th.col-sm-3
Unit cost/Hr rate
%th.col-sm-3
Qty
%th.col-sm-2
%th.col-sm-3
Amount
%tbody
- #invoice.items.each do |item|
%tr.sortable-table
%th
= item.id
%th
= item.name
%th
= number_to_currency item.unit_cost
%th
= item.qty
%th
%th
- amount = number_to_currency(item.unit_cost * item.qty)
= amount
%hr
.row
.col-sm-6
.col-sm-3
.col-sm-3
%b
Subtotal
- sum = 0
- #invoice.items.each do |item|
- if item.qty?
- subtotal = (item.unit_cost * item.qty)
- sum += subtotal
= number_to_currency(sum)
%p
%b
Tax
= number_to_currency(sum * (#invoice.tax/100))
%p
%h4
%b
Total
= number_to_currency((sum * (#invoice.tax/100)) + sum)
%hr
= link_to 'Edit', edit_invoice_path(#invoice)
\|
= link_to 'Back', invoices_path
But in invoices/_invoice.html.erb I have the error :
%h1 Listing invoices
%table.table.table-striped.table-hover
%thead
%tr.sortable-table
%th
Id
%th
Job Id
%th
Item
%th
Unit cost
%th
Qty
%th
Amount
%tbody
= render #invoices
%br
= link_to 'New Invoice', new_invoice_path
<tr>
<td>
<%= invoice.id %>
</td>
<td>
<%= invoice.job_id %>
</td>
<td>
</td>
<td>
<%= invoice.unit_cost %>
</td>
<td>
<%= invoice.qty %>
</td>
<td>
<%= invoice.job.customer_name %>
</td>
<td>
<%= link_to 'Details', invoice, class: 'btn btn-primary btn-xs' %>
</td>
<td>
<%= link_to "", edit_invoice_path(invoice), id: "edit_#{invoice.id}", class: 'glyphicon glyphicon-pencil index-icons' %>
</td>
<td>
<%= link_to "", invoice_path(invoice), method: :delete, id: "delete_invoice_#{invoice.id}_from_index", class: 'glyphicon glyphicon-trash index-icons', data: {confirm: 'Are you sure ?'} %>
</td>
</tr>
Thank you, and if you need more code let me know.
Update:
[you see invoice Id 47 have job id 67][1]
[the job id 67 is exist][2]
[on the invoice show I have name of customer][3]
[1]: https://i.stack.imgur.com/ODAkb.png
[2]: https://i.stack.imgur.com/uGK21.png
[3]: https://i.stack.imgur.com/sRTWS.png

NoMethodError in Invoices#index undefined method `customer_name' for
nil:NilClass.
This means where you are calling customer_name:
#invoice.job.customer_name.capitalize.html_safe
You are calling it on nil, or in other words:
#invoice.job
returns nil. If the invoice does not have a job associated with it, any methods involving the invoice's job will fail (apart from just #invoice.job, which will return nil).
Your two options are to either make sure every invoice has a job associated with it before rendering, or to rewrite your view template as:
.container.invoice
.row
.col-sm-6
- if current_user.logo.present?
= image_tag current_user.logo.url(:thumb)
- else
= image_tag 'blank.jpg'
.col-sm-3
.col-sm-3
%h3
= current_user.full_name.titleize
%p
= current_user.email
%p
= current_user.phone
%hr
.row
.col-sm-6
- if #invoice.job
%h4
Customer :
= #invoice.job.customer_name.capitalize.html_safe
%p
%b
Phone:
= #invoice.job.customer_tel
%p
%b
Email:
= #invoice.job.customer_email
.col-sm-3
.col-sm-3
%p
%b
Invoice: #
= #invoice.id
%p
%b
This will only display the bottom section of the view if a job is associated with the #invoice

Related

how to execute function after cocoon add the record?

I'm using the cocoon gem in my rails project, and I have two "link_to_add_association", but I need that depending on which link_to is pressed to do a certain function, link_to with id "link_1" adds the records to the beginning of the table and the other one adds the records at the end with other values, this is my partial form:
= form_for([#billing, #payment]) do |f|
- if #payment.errors.any?
= render partial: 'layouts/partials/errors/form_errors', locals: { errors: #payment.errors }
= f.hidden_field :billing_id, value: #billing.id
.row
.col-md-6
.form-group.row
.col-md-4
= f.label :payment, class: 'form-control-label'
.col-md-8
= f.text_field :payment, class: 'form-control text-right', 'data-currency-format--live': '', 'data-target': '#total-pay'
.col-md-6
.form-group.row
.col-md-4
= f.label :day, class: 'form-control-label'
.col-md-6
= f.text_field :day, class: 'form-control datepicker', 'data-startView': 'days', 'data-minyear': #billing.date_bill.year, 'data-minmonth': #billing.date_bill.month, 'data-minday': #billing.date_bill.day
.col-md-1
.links
= link_to_add_association 'add', f, :payment_details, partial: 'payment_detail_fields',:"data-association-insertion-node" => "tbody.details",:"data-association-insertion-method" => "prepend", class:"btn btn-success btn-xs", id: "link_1"
.col-md-1
.links
= link_to_add_association 'add', f, :payment_details, partial: 'payment_detail_discount_fields',:"data-association-insertion-node" => "tbody.details",:"data-association-insertion-method" => "append", class:"btn btn-success btn-xs", id: "link_2"
.col-md-12
#payment_details
%table.tabla_personalizada
%thead
%tr
%th value_paid
%th voucher
%th accion
%th value_paid
%th value_paid
%th voucher
%th accion
%tbody.details
= f.fields_for :payment_details do |payment_detail|
= render 'payment_detail_fields', f: payment_detail
%tr
%td
%td
%td
%td
%td
%td
%td
%tr.descuentos
%td Descuento
%td Descuento
%td
%td
%td
%td
%td
.row
.col-md-12
= f.label :comments, class: 'form-control-label'
= f.text_area :comments, class: 'form-control', rows: 6
%hr
.row
.col-md-8
.form-group.row
.col-md-8
= f.submit :class => 'btn btn-primary'
- content_for :javascript do
:javascript
$(document).ready(function() {
$("#link_1").on("cocoon:after-insert", function() {
alert("element of link_1");
} )
$("#link_2").on("cocoon:after-insert", function() {
alert("element of link_2");
} )
});
I tried this code but I can't find a way to make it work
$(document).ready(function() {
$("#link_1").on("cocoon:after-insert", function() {
alert("element of link_1");
} )
$("#link_2").on("cocoon:after-insert", function() {
alert("element of link_1");
} )
});

Two submission forms with form-tag on same page in rails

I have a weekly time entry form currently. How can i have another time entry form on the same page ? and these two forms need be submitted separately as different records. Any help would be appreciated .
Here is my code:-
show_weeks.html.erb
<div class="table-responisve>
<% if #dates != nil %>
<table class="table-bordered">
<thead>
<tr>
<% #dates.each do |date| %>
<th><%=date.to_s+","+date.strftime("%A").to_s %> </th>
<% end %>
</thead>
<tbody>
<tr>
<% #dates.each do |date| %>
<% if #time_entry %>
<td><%= text_field_tag "#{date}", #time_entry.hour_per_day["#{date}"], class: "dates" %></td>
<% else %>
<%if date < Date.today %>
<td> <%= text_field_tag "#{date}", "", class: "dates" %> </td>
<%else %>
<td><%= text_field_tag "#{date}", "", class: "dates" if date == Date.today && Time.now.strftime("%H").to_i >= 10 %> </td>
<% end %>
<% end %>
<% end %>
</tr>
<tr>
<% if #time_entry %>
<td colspan="2"> Please Enter your Comment </td>
<td colspan="5">
<% #time_entry.comments.each do |c| %>
<p><%= text_field_tag "Comment", c.message %> </p>
<% end %>
</td>
<%else%>
<td colspan="2"> Please Enter your Comment </td>
<td colspan="5"><%= text_field_tag "Comment", "" %>
</td>
<%end%>
</tr>
</tbody>
</table>
</div>
<button type="button" class="btn btn-primary"
id="save_entries">Submit</button>
<%= form_tag save_time_entries_path, method: 'post',
id:"save_time_entries" do %>
<%= hidden_field_tag "start_date", #dates.first%>
<%= hidden_field_tag "end_date", #dates.last%>
<%= hidden_field_tag "total_hours", "" %>
<%= hidden_field_tag "project_id", #project.id %>
<%= hidden_field_tag "time_entry", "" %>
<%= hidden_field_tag "message", "" %>
<% if #time_entry%>
<%= hidden_field_tag "time_entry_detail_id", #time_entry.id %>
<% end %>
<% end %>
<script>
$("#save_entries").click(function(){
var time_entry = []
var hours = 0;
var message = document.getElementById("Comment").value;
$('.dates').each(function() {
hours += Number($(this).val());
if ($(this).val() == 0)
{
time_entry.push($(this).attr('name'),0)
}else{
time_entry.push($(this).attr('name'),$(this).val())
}
});
if (hours > 60) {
alert("Total Hours Should be equal to 60");
return false;
}
else {
$("#message").val(message);
$("#time_entry").val(time_entry);
$("#total_hours").val(hours);
$("#save_time_entries").submit();
}
})
</script>
<%end%>
you can create 2 different forms with form_for, it shouldn't be a problem
I figure out solution. Using of two submission forms on same page is bad idea. So I have create previous weeks records by using after create call back and i given default values for TimeEntryDetail. Here it creates all weeks records in background. Suppose if you skipped for 6 weeks , it'll create 6 empty records in background. Here is my working code
Modal.rb
after_create :chceck_time
def check_time
#project_mem_check= ProjectMember.where(project_id: project, member_id: user).first.created_at
#present week dates coming here |
#time_entry_check = TimeEntryDetail.where(project_id: project, user_id: user).first.created_at
if #time_entry_check.nil?
#time_entry_check=#project_mem_check
end
#last_week_start=Date.today.beginning_of_week
#last_week_end =Date.today.end_of_week
#cheking project member creation shall be less than time entry creation of that project.
if #project_mem_check <= #time_entry_check
#time_check_first=TimeEntryDetail.where(project_id: project, user_id: user).pluck(:start_date).first.to_date
#time_check_last =TimeEntryDetail.where(project_id: project, user_id: user).pluck(:start_date).last.to_date
#check first entry == last time entry
if #time_check_first==#time_check_last
pm=ProjectMember.where(project_id: project, member_id: user).first.created_at.to_date
tm=Date.today.to_date
unfilled_weeks= ((tm-pm)/7).to_i+1
unfilled_weeks.times {
#last_week_start= #last_week_start-7
#last_week_end = #last_week_end-7
#call_back_entry=TimeEntryDetail.create(start_date: (#last_week_start).to_date, end_date: (#last_week_end).to_date,
project_id: project.id, user_id: user.id, hours: 0, aasm_state: "pending", hour_per_day: "" )
#call_back_entry.comments << Comment.create(message: "Please fill the timesheet ")
}
else
#Already this user have time entries and create empty records from where he stopped.
pm=created_at.to_date #--.present time entry is coming
tm=Date.today.to_date
unfilled_weeks= ((tm-pm)/7).to_i+1
unfilled_weeks.times{
#last_week_start= #last_week_start-7
#last_week_end = #last_week_end-7
#call_back_entry=TimeEntryDetail.create(start_date: (#last_week_start).to_date, end_date: (#last_week_end).to_date,
project_id: project.id, user_id: user.id, hours: 0, aasm_state: "submitted", hour_per_day: "" )
#call_back_entry.comments << Comment.create(message: "Not yet filled this week ")
}
end
end
end

Cant get the Edit function Working

I have two models Employee and Overtime Definition The Associations are set like this
Employee
class Employee < ActiveRecord::Base
has_many :overtime_definitions
Overtime Definition
class OvertimeDefinition < ActiveRecord::Base
belongs_to :employee
I created an Overtime definition for an employee and it all looks fine.However I'm having trouble with editing the same for an employee.
overtime_definitions__controller:
def new
#flag = params[:flag]
#employee = Employee.find(params[:id])
#overtime = OvertimeDefinition.new
end
def create
#employee = Employee.find(params[:overtime_definition][:employee_id])
#overtime = OvertimeDefinition.new(params[:overtime_definition])
if (params[:half_day_extra_duty_hours][:hour].to_s !="" || params[:half_day_extra_duty_hours][:minute].to_s !="")
#overtime.half_day_extra_duty_hours = params[:half_day_extra_duty_hours][:hour].to_s + ":" + params[:half_day_extra_duty_hours][:minute].to_s + ":" + "00"
else
#overtime.half_day_extra_duty_hours = nil
end
if (params[:full_day_extra_duty_hours][:hour].to_s !="" || params[:full_day_extra_duty_hours][:minute].to_s !="")
#overtime.full_day_extra_duty_hours = params[:full_day_extra_duty_hours][:hour].to_s + ":" + params[:full_day_extra_duty_hours][:minute].to_s + ":" + "00"
else
#overtime.full_day_extra_duty_hours = nil
end
if #overtime.save
flash[:notice] = "Overtime Successfully Created for #{#employee.name}"
redirect_to :action => 'search_overtime'
end
end
def edit
#flag = params[:flag]
#overtime = OvertimeDefinition.find(params[:id][:employee_id])
#employee = Employee.find(params[:id])
end
def update
#employee = Employee.find(params[:id])
#overtime = OvertimeDefinition.find(params[:id])
if #overtime.update_attributes(params[:overtime_definition])
flash[:notice] = "Overtime Successfully Updated for #{#employee.name}"
redirect_to :action => 'search_overtime'
else
render :action => 'edit',:flag=>params[:flag]
end
end
Tried with these in the edit method
#overtime = OvertimeDefinition.find(params[:id][:employee_id])
#gives me can't convert Symbol into Integer error.
#overtime = OvertimeDefinition.find(params[:id])
#gives me Couldn't find OvertimeDefinition with ID=1353 error.Actually 1353 is the id of that employee.
3.#overtime = OvertimeDefinition.find(params[:employee_id])
#gives me couldn't find OvertimeDefinition without an ID error.
My _search_overtime_employee_list having these links for new and edit actions
<%=link_to "Calculation" ,:action => "new",:id=>employee.id, :flag=>"Calculation" %>
<%= link_to "Re-Calculate",:action => "edit",:id=>employee.id,:flag=>"Re-Calculate" %>
new.rhtml
<%= form_tag :action => 'create' do %>
<%= render :partial =>'form'%>
<center>
<%= submit_tag "Save",:onclick=>"return validate()",:class=>"buttons"%>
</center>
<% end %>
<%= link_to "Back" ,:action => "search_overtime" %>
edit.rhtml
<%= form_tag :action => 'update', :id=>#employee.id,:flag=> params[:flag],:value=>params[:id] %>
<%= render :partial =>'form'%>
<center>
<%= submit_tag "Update",:onclick=>"return validate()",:class=>"buttons"%>
</center>
<%= link_to "Back" ,:action => "search_overtime" %>
_form.rhtml
Employee Details
<table cellspacing="5">
<tr>
<td><b>Employee Code</b></td>
<%= hidden_field 'overtime_definition','employee_id',:value=>params[:id] %>
<td><%= #employee.employeeid %></td>
<td><b>Employee Name</b></td>
<td><%= #employee.personnel.display_full_name %></td>
</tr>
<tr>
<td><b>Department</b></td>
<td><%= #employee.department ? #employee.department.name : "" %></td>
<td><b>Designation</b></td>
<td><%= #employee.designation ? #employee.designation.name : "" %></td>
<td><b>Location</b></td>
<td><%= #employee.location.name%></td>
</tr>
</table>
</br>
<fieldset>
<table cellspacing="5">
<%= form_for :overtime_definition, :builder => LabelFormBuilder do |od| %>
<tr>
<td>
<label for="half_day_extra_duty_hours">
Half Day Extra Duty Hours
</label>
</td>
<td class ="datefamily">
<%= select_time(#overtime.half_day_extra_duty_hours, {:include_blank => true, :time_separator => ":",:prefix => "half_day_extra_duty_hours"})%>
</td>
</tr>
<tr>
<td>
<label for="full_day_extra_duty_hours">
Full Day Extra Duty Hours
</label>
</td>
<td class ="datefamily">
<%= select_time(#overtime.full_day_extra_duty_hours, {:include_blank => true, :time_separator => ":",:prefix => "full_day_extra_duty_hours"})%>
</td>
</tr>
<tr>
<%= od.sr_check_box :is_salary_basis, {}, true, false, :label => "Is Salary Basis"%>
</tr>
<tr>
<%= od.sr_check_box :is_fixed_amount, {}, true, false, :label => "Is Fixed Amount"%>
<td colspan="2" id="ov_hm" style="display: none">
Half Day Amount
<%= od.text_field :half_day_amount, :onkeypress => "return numbersonly(event)", :style => "width:40px" %>
</td>
<td colspan="2" id="ov_fm" style="display: none">
Full Day Amount
<%= od.text_field :full_day_amount, :onkeypress => "return numbersonly(event)", :style => "width:40px" %>
</td>
</tr>
<%end%>
</table>
I just lost out here completely in getting that edit action work.Any help is greatly appreciated!
Your current edit link is:
<%= link_to "Re-Calculate",:action => "edit",:id=>employee.id,:flag=>"Re-Calculate" %>
In your edit action:
#overtime = OvertimeDefinition.find(params[:id][:employee_id]) ## gives me can't convert Symbol into Integer error.
As per the edit link, you are directly passing :id in query params which you can access as params[:id]. There is no params[:id][:employee_id] in your params hash so when you say params[:id][:employee_id] Ruby tries to convert :employee_id to an integer which is a symbol. Hence, the error.
I think you should be passing id of OvertimeDefinition record in :id from your link. And access it as
#overtime = OvertimeDefinition.find(params[:id])
in the Controller's action.
#overtime = OvertimeDefinition.find(params[:id]) ## gives me Couldn't
find OvertimeDefinition with ID=1353 error.Actually 1353 is the id of
that employee.
This is because you are passing employee id in params[:id] so obviously this will not work. You need to pass OvertimeDefinition id here.
#overtime = OvertimeDefinition.find(params[:employee_id]) ## gives me
couldn't find OvertimeDefinition without an ID error.
You are not passing any :employee_id in query params within edit link. So, params[:employee_id] will be nil and find method fails because you didn't pass any id to it.
Solution :
Update your edit link as below:
<%= link_to "Re-Calculate",:action => "edit",:id=> #overtimedefinition.id , :employee_id => employee.id,:flag=>"Re-Calculate" %>
Replace #overtimedefinition.id with appropriate id of OvertimeDefinition record. As you have not shared the code, I don't know the name of OvertimeDefinition variable.
Update your edit action as:
def edit
#flag = params[:flag]
#overtime = OvertimeDefinition.find(params[:id])
#employee = Employee.find(params[:employee_id])
end

Stripe - Creating a new card for customer

I am trying to implement the ability for a customer to create a new card.
I have created a form in which the customer creates a new card:
<table class="table">
<%= simple_form_for(#user, :url => billing_path, html: {class: 'form-horizontal' }) do |f| %>
<tr>
<td>Country</td>
<td><%= f.text_field :saddress_country, value: card1.address_country %> </td>
</tr>
<tr>
<td>Billing Address</td>
<td><%= f.text_field :sbilling_address1, value: card1.address_line1 %> </td>
<td><%= f.text_field :sbilling_address2, value: card1.address_line2 %> </td>
</tr>
<tr>
<td>City / State / Zip</td>
<td><%= f.text_field :saddress_city, value: card1.address_city %> </td>
<td><%= f.text_field :saddress_state, value: card1.address_state %> </td>
<td><%= f.text_field :saddress_zip, value: card1.address_zip %> </td>
</tr>
<tr>
<td>Credit Card Number </td>
<td><%= f.text_field :scardnumber, placeholder: card1.last4, value: cardnumberempty %></td>
<td><%= f.text_field :scvc, placeholder: "CVC", value: cvcempty %></td>
</tr>
<tr>
<td>Card's Info</td>
<td><%= f.text_field :sname, value: card1.name %> </td>
<td><%= f.text_field :sexp_month, value: card1.exp_month %> </td>
<td><%= f.text_field :sexp_year, value: card1.exp_year %> </td>
</tr>
<tr><td><%= f.submit %></td></tr>
<% end %>
</table>
And then in the controller I grab the information and create the new card:
def create_card_stripe
#user = current_user
customer = Stripe::Customer.retrieve(current_user.stripe_customer_token)
customer.cards.create({
:card => current_user.stripe_card_token,
:number => params[:user][:scardnumber],
:exp_month => params[:user][:sexp_month],
:exp_year => params[:user][:sexp_year],
:cvc => params[:user][:scvc],
:name => params[:user][:sname],
:address_line1 => params[:user][:saddress_line1],
:address_line2 => params[:user][:saddress_line2],
:address_city => params[:user][:saddress_city],
:address_zip => params[:user][:saddress_zip],
:address_state => params[:user][:saddress_state],
:address_country => params[:user][:saddress_country]
})
#user.update_attribute(:stripe_card_id, customer.active_card.id)
if customer.save
flash.alert = "Billing information updated successfully!"
redirect_to edit_user_registration_path
else
flash.alert = "Stripe error"
redirect_to edit_user_registration_path
end
end
When I submit the form I get the following error that comes from Stripe:
"Received unknown parameters: number, exp_month, exp_year, cvc, name, address_city, address_zip, address_state, address_country".
So what it says is that I am sending wrong parameters. But if you check here those parameters are there (Child parameters).
Any clue on what I am doing wrong? Any guidance at all on how to create a new card using the Stripe API will be really helpful. Thank you.
There is two ways of adding a card using Stripe.
1) Using the card token. If you have a token, like you do, you don't need anything else, so you can just do
customer.cards.create({
:card => current_user.stripe_card_token
})
2) You could also do this:
customer.cards.create({
:card => {
:number => params[:user][:scardnumber],
:exp_month => params[:user][:sexp_month],
:exp_year => params[:user][:sexp_year],
:cvc => params[:user][:scvc],
:name => params[:user][:sname],
:address_line1 => params[:user][:saddress_line1],
:address_line2 => params[:user][:saddress_line2],
:address_city => params[:user][:saddress_city],
:address_zip => params[:user][:saddress_zip],
:address_state => params[:user][:saddress_state],
:address_country => params[:user][:saddress_country]
}
})
So as you can see here, the important thing is that the details are nested into the card attribute.
Evidently, you've done a mix of the two, you are best off choosing one (token is better) and sticking with it. Is that clear?

Sorting nested form fields in rails

I'm trying to create an inventory form that sorts the products based on their category. Ideally I'll be able to have these products listed by category, and will put in some javascript to hide/show products of a given category.
Currently, I'm having trouble wrapping my head around how to split my products up by category in my form. Here's what I currently have (modeled after Ryan Bates' Railscasts for nested attributes):
class InventoriesController < ApplicationController
def new
#title = "Take Inventory"
#vendor = ProductVendor.find(params[:product_vendor_id])
#inventory = Inventory.new()
#products = #vendor.products.active
#products.each do |product|
#inventory_line_item = #inventory.inventory_line_items.build({:product_id => product.id})
end
end
My form for a new inventory:
<%= form_for #inventory do |f| %>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
</tr>
<% f.fields_for :inventory_line_items do |builder| %>
<tr>
<td><%= builder.object.product.name %></td>
<td><%= builder.text_field(:quantity, :size => 3) %></td>
<%= builder.hidden_field :product_id %>
</tr>
<% end %>
</table>
<%= f.hidden_field(:user_id, :value => current_user.id) %>
<%= f.hidden_field(:location_id, :value => current_location.id) %>
<%= f.hidden_field(:product_vendor_id, :value => #vendor.id) %>
<%= f.submit "Submit" %>
<% end %>
So I have another model called product_category that has_many products. How do I sort and separate my products by category in the controller and form? Also, is there a way to do this using Formtastic? Thanks!
It's actually pretty simple to implement. Add a hidden field in the nest_form field with the attribute position (add this attr to your model of course) and add this to your js along with using the jquery-ui.js
$('#task_fields').sortable({
items: '.fields',
dropOnEmpty: true,
cursor: 'move',
handle: '.move',
opacity: 0.4,
scroll: true,
axis:'y',
placeholder: 'ui-state-highlight',
start: function(e, ui) {
ui.placeholder.height(ui.item.height());
},
update: function() {
$(this).children(".fields").each(function(index) {
$(this).children('input.task_position').val(index + 1);
});
}
});
here's what I have in my _form.html.haml
= f.fields_for :tasks do |t|
= t.text_field :name
= t.hidden_field :position, :class => :task_position
= t.collection_select :account_id, Account.all, :id, :full_name, :prompt => 'Assign task to...'
.button-group
%span{:class => "button icon no-text move pill"}
= t.link_to_remove "", :class => "button icon no-text remove pill"
= f.link_to_add "Add a Task", :tasks, :class => "button icon add"
This worked really well.

Resources