Access parent attribute in independent nested model view - ruby-on-rails

I have nested resources
resources :invoices do
resources :payments
end
The invoices model is as follows:
class Invoice < ActiveRecord::Base
belongs_to :customer, :inverse_of => :invoices
attr_accessible :due_date, :invoice_date, :reading_ids, :customer_id, :customer, :status, :amount, :balance
has_many :invoice_items, :dependent => :destroy
has_many :payments, :dependent => :destroy
end
The payments model is as follows:
class Payment < ActiveRecord::Base
attr_accessible :amount, :method, :payment_date, :reference_no, :invoice_id
belongs_to :invoice
end
The payments controller is as follows:
class PaymentsController < ApplicationController
before_filter :authenticate_user!
def new
invoice = Invoice.find(params[:invoice_id])
#payment = invoice.payments.build
respond_to do |format|
format.html #new.html.erb
end
end
end
I have created a view to record new payments and would like to display the customer details (name in particular) in this view, how do i go about it?
Payments view
<%= simple_form_for [#payment.invoice, #payment], :html => { :class => 'form-horizontal' } do |f| %>
<%= render "shared/error_messages", :target => #payment %>
<h5> Invoice Details </h5>
<%= f.input :invoice_id, disabled: true, as: :string %>
<%= f.input :method, as: :select, :collection => [['Cash','Cash'],['Cheque','Cheque'],['In-House transfer','In-House transfer'],['Account Ledger','Account ledger']], :selected => ['Cash','Cash'] %>
<%= f.input :reference_no, as: :string %>
<%= f.input :payment_date, as: :string, input_html: { class: "datepicker" } %>
<% end %>

Just use:
<%= #payment.invoice.customer.name %>
anywhere in the view.

Related

Rails nested attributes "no implicit conversion of Symbol into Integer" for has_many association

I've following are the Model codes.
user.rb
has_many :teams, dependent: :destroy
has_many :companies, dependent: :destroy
after_create :create_tables!
def create_tables!
companies.create!
Team.create!(user_id: self.id, company_id: Company.where(user_id: self.id).first.id)
end
company.rb
belongs_to :user
has_many :teams, inverse_of: :company, dependent: :destroy
has_many :users, through: :teams
accepts_nested_attributes_for :teams
team.rb
belongs_to :user
belongs_to :company, inverse_of: :teams
Following are my Controller codes
companies_controller.rb
def new
#company = current_user.companies.new
#company.build_teams
end
def update
current_user.companies.first.update_attributes(company_params)
respond_to {|format| format.js}
end
private
def company_params
params.require(:company).permit(:name, :about, :problem, :solution, :logo, :url, :email, :phone, :category, :started_in,
teams_attributes: [:position, :admin])
end
In views
<%= form_with model: #company, method: :put do |f| %>
<%= f.fields_for :teams_attributes, #company.teams.first do |team| %>
<%= team.hidden_field :admin, value: true %>
<%= team.text_field :position, placeholder: 'Eg: CEO', class: 'input' %>
<% end %>
<%= f.submit 'Next' %>
<% end %>
When i try this in rails console it works and saved in db, in views params are also passing good. Its below
But in views it says
TypeError in CompaniesController#update no implicit conversion of Symbol into Integer
It should be f.fields_for :teams instead of f.fields_for :teams_attributes
<%= form_with model: #company, method: :put do |f| %>
<%= f.fields_for :teams, #company.teams.first do |team| %>
<%= team.hidden_field :admin, value: true %>
<%= team.text_field :position, placeholder: 'Eg: CEO', class: 'input' %>
<% end %>
<%= f.submit 'Next' %>
<% end %>

nested form "Can't mass-assign protected attributes"

I have 3 models; Quote, Item, and Product.
My quote/new.html.erb is set up to render a partial which contains the item form, and in that item form a partial is rendered to choose a product.
the error: ActiveModel::MassAssignmentSecurity::Error in QuotesController#create
"Can't mass-assign protected attributes: products"
(I edited out irrelevant stuff in the following)
Quote.rb
class Quote < ActiveRecord::Base
attr_accessible :items_attributes
has_many :items, :dependent => :destroy
accepts_nested_attributes_for :items
end
Item.rb
class Item < ActiveRecord::Base
attr_accessible :price, :product_attributes
belongs_to :quote
belongs_to :product
accepts_nested_attributes_for :product
end
Product.rb
class Product < ActiveRecord::Base
attr_accessible :name, :item_make
has_many :items
accepts_nested_attributes_for :items
end
new.html.erb
<%= simple_nested_form_for #quote do |m| %>
<%= m.simple_fields_for :items, :html => { :multipart => true } do |quoteform| %>
<%= render "form", f: quoteform %>
<% end %>
<%= m.link_to_add "Add an item", :items %>
<%= m.button :submit %>
<% end %>
_form.html.erb
<%= f.simple_fields_for :products, :html => { :multipart => true } do |x| %>
<% render "layouts/styleselect", g: x %>
<% end %>
_styleselect.html.erb
<% g.hidden_field :item_make, :value => #item.make %>
<%= g.input :name, collection: Product.where(:item_make => 1), label: false, input_html: {:id=>"sst_style"} %>
So basically the nested form goes Quote->Item->Product, but item belongs to product, which maybe is causing the problem? I tried adding product_attributes or products_attributes to both the item model and the quote model, and the same with accepts_nested_attributes_for product(s).
Any help would be appreciated, thanks.
Looks like you need to make products singular.
<%= f.simple_fields_for :product, :html => { :multipart => true } do |x| %>
<% render "layouts/styleselect", g: x %>
<% end %>
You currently have:
<%= f.simple_fields_for :products, :html => { :multipart => true } do |x| %>

How to filter or scope physician in a form only to list physician that belongs to an organization?

When creating an appointment, for let say Organization 'ABC', I can also see physicians that belongs to other organization. It suppose to only list physician from 'ABC' and not others. How should I go about this.
Thank you.
My Appointment form:
<%= simple_form_for(#appointment, :html => { :class => 'form-horizontal' }) do |f| %>
<div class="form-inputs">
<%= f.hidden_field :patient_id %>
<%= f.association :physician, :label_method => :first_name, :include_blank => false, :as => :radio_buttons, :required => true %>
<%= f.hidden_field :appointment_date, :value => DateTime.now %>
<%= f.hidden_field :organization_id, :value => current_user.organization_id%>
</div>
<div class="form-actions">
<%= f.button :submit, "Create Appointment" %>
</div>
<% end %>
My models:
/app/models/physician.rb
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
belongs_to :organization
attr_accessible :physician_name, :organization_id
end
/app/models/appointment.rb
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
belongs_to :organization
attr_accessible :physician_id, :patient_id, :appointment_date, :state, :organization_id
end
/app/models/patient.rb
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
belongs_to :organization
attr_accessible :patient_name, :organization_id
end
My Controllers:
/app/controllers/appointment_controller.rb
class AppointmentsController < ApplicationController
def new
#appointment = Appointment.new
#appointment.patient_id = params[:patient_id]
end
def create
#appointment = Appointment.new(params[:appointment])
if #appointment.save
flash[:notice] = "New appointment record created"
redirect_to dashboards_path
else
render 'new'
end
end
end
This is because simple_form does not know about your scopes. If you tell it:
<%= f.association :phyisician %>
it will simply list all available physicians in the database.
The solution is to give it the collection of physicians you want to show, for example you could write:
<%= f.association :physician,
:collection => #appointment.patient.organization.physicians,
:label_method => :first_name,
:include_blank => false,
:as => :radio_buttons,
:required => true %>

Can't mass-assign protected attributes: category_ids

I'm using simple_form, and I just want to create association between categories and articles using categorization table.
But I have this error:
Can't mass-assign protected attributes: category_ids.
app/controllers/articles_controller.rb:36:in `update'
articles_controller.rb
def update
#article = Article.find(params[:id])
if #article.update_attributes(params[:article]) ---line with the problem
flash[:success] = "Статья обновлена"
redirect_to #article
else
render :edit
end
end
article.rb
has_many :categorizations
has_many :categories, through: :categorizations
category.rb
has_many :categorizations
has_many :articles, through: :categorizations
categorization.rb
belongs_to :article
belongs_to :category
categorization has article_id and category_id fields.
My _form.html.erb
<%= simple_form_for #article, html: { class: "form-horizontal", multipart: true } do |f| %>
<%= f.error_notification %>
<%= f.input :title %>
<%= f.association :categories %>
<%= f.input :teaser %>
<%= f.input :body %>
<%= f.input :published %>
<% if #article.published? %>
<%= f.button :submit, value: "Внести изменения" %>
<% else %>
<%= f.button :submit, value: "Опубликовать" %>
<% end %>
<% end %>
do you have attr_accessible in article.rb?
if so add
attr_accessible :title, :category_ids
Also make sure you really want this for all forms... If not add this:
attr_accessible :title, :category_ids, :as => :admin
then
#article = Article.new
#article.assign_attributes({ :category_ids => [1,2], :title => 'hello' })
#article.category_ids # => []
#article.title # => 'hello'
#article.assign_attributes({ :category_ids => [1,2], :title => 'hello' }, :as => :admin)
#article.category_ids # => [1,2]
#article.title # => 'hello'
#article.save
or
#article = Article.new({ :category_ids => [1,2], :title => 'hello' })
#article.category_ids # => []
#article.title # => 'hello'
#article = Article.new({ :category_ids => [1,2], :title => 'hello' }, :as => :admin)
#article.category_ids # => [1,2]
#article.title # => 'hello'
#article.save
The form field created by
<%= f.association :categories %>
is going to set the attribute category_id, but the attribute is protected. In you model you should have a line of code looks like this:
attr_accessible :title, :teaser, :body, :published
these attributes are allowed for mass assignment. If you want the form to set category_id you have to add these attribute to the attr_accessible method:
attr_accessible :title, :teaser, :body, :published, :category_id
This should fix your issue.

Help with Formtastic

First of all I'm no native speaker and just begun with rails three days ago. Sorry for my mistakes.
Formtastic is driving me crazy. I have three tables: user, note, receiver:
class User < ActiveRecord::Base
has_many :receivers
has_many :notes, :through => :receivers
attr_accessible :id, :email, :password, :password_confirmation, :remember_me
class Note < ActiveRecord::Base
has_many :receivers
has_many :users, :through => :receivers
attr_accessible :id, :text, :user_id
accepts_nested_attributes_for :receivers
class Receiver < ActiveRecord::Base
belongs_to :user
belongs_to :note
attr_accessible :user_id, :note_id, :note_attributes
accepts_nested_attributes_for :user
accepts_nested_attributes_for :note
And here my formtastic form:
<%= semantic_form_for #note do |form| %>
<%= form.inputs do %>
<%= form.input :text %>
<%= form.input :user_id, :as => :check_boxes, :collection => User.find(:all, :conditions => ["id != ?", current_user.id], :order => 'id').collect{|u| [u.email, u.id]} %>
<% end %>
<%= form.buttons %>
<% end %>
Now I want to create a new note which can have several receivers. Unfortunately only the note is created, but no entrys in the receiver table, even if I select receivers. Can someone help me please?
Here my notes_controller:
#note = Note.new(params[:note])
Print out the params[:note] using logger.info and check what all parameters are passed from form and Can you also try adding code reciever_ids code as attr_accessible in Note model
In the view model, you are using attr_accessible, it wont save any fields that are not in the attr_accessible like the receives_attributes, that comes from the form when your nested form is displayed. So you have to add receiver_attributes to the attr_accessible list.You might want to do this to the User and Receiver(if you are having nested forms for them too), which also have attr_accessible
attr_accessible :id, :text, :user_id, :receiver_attributes
In the new action of notes_controller, you need to use build method like
#note.build_receiver
then in the form, you need to write the code to display the fields in the receiver.
<%= semantic_form_for #note do |form| %>
<%= form.inputs do %>
<%= form.input :text %>
<%= form.input :user_id, :as => :check_boxes, :collection => User.find(:all, :conditions => ["id != ?", current_user.id], :order => 'id').collect{|u| [u.email, u.id]} %>
<% end %>
<%=f.semantic_fields_for :receiver_attributes, #note.receiver do|receiver| %>
<!-- Add receiver related input here using the receiver block variable like receiver.input -->
<% end %>
<%= form.buttons %>
<% end %>

Resources