i have the following nested form :
<%= form_for #contrat,:url => backend_orders_update_report_url(#contrat) do |f| %>
<%= f.fields_for :contrat_lines do |fcl| %>
<%= fcl.object.inspect %>
<% end %>
<% end %>
the output is the following :
nil
In the nested forms i want to display a few elements not as form but as raw text and a few ones as form field. Usually in a form by doing f.object.name, i would access the name and be able to display it as I want. However, here if i do fcl.object, there is only nil. It should display the inspection of a contrat_line object.
Is it possible to access the data in a nested form?
EDIT :
the controller action :
def show_report
#contrat = Contrat.find(params[:id])
end
Here is what models look like with the relation at the beggining :
ContratLine :
class ContratLine < ActiveRecord::Base
include Priceable
belongs_to :contrat
belongs_to :good
#a enlever ici et dans la base
attr_accessible :active_start,:active,:good_id,:pricing,:contrat
validates :active_start, :presence=> true,:if => "active"
validate :active_start_smaller_than_active_stop
validate :active_start_day_cannot_be_greater_than_28
has_one :pricing, :as => :priceable, :dependent => :delete
before_validation :convert_month_year_to_date
after_save :set_user_subscription_date
Contrat :
class Contrat < ActiveRecord::Base
has_many :contrat_lines, :dependent => :delete_all
belongs_to :user
attr_accessible :user_id,:pricing_id,:state,:adresse_id,:adresse,:payment,:adresse_attributes,:automatic,:start_date,:end_date
enum_attr :state, %w(basket waiting_data to_confirm paid) do
labels :basket=>'Panier', :to_confirm=>'Non payé',:paid=>'Payé'
end
enum_attr :payment, %w(debit_card wire_transfer cheque direct_debit)
belongs_to :adresse
accepts_nested_attributes_for :adresse, :allow_destroy => true
scope :by_state, lambda { |state| where("state = ?",state) }
scope :last_automatic, where("automatic = true").order("invoice_date DESC")
scope :last_with_adresse, where("state != 'basket'").order("invoice_date DESC")
before_validation :set_numbers
You're missing an accepts_nested_attributes_for :contrat_lines as well as :contrat_lines_attributes in attr_accessible
Related
In my Rails 3 application, I have the following simple relational structure:
class Rollout < ActiveRecord::Base
has_many :items, :through => :rollout_items
end
class RolloutItem < ActiveRecord::Base
belongs_to :rollout
belongs_to :item
end
class Item < ActiveRecord::Base
has_many :rollouts, :through => :rollout_items
end
Controller:
def new
#rollout = Rollout.new
end
I get the above error with the following form:
<%= simple_form_for #rollout do |f| %>
<%= f.association :items %>
<% end %>
There is a missing relationship between Rollout and RolloutItem:
class Rollout < ActiveRecord::Base
has_many :rollout_items # This.
has_many :items, :through => :rollout_items
end
The same goes for Item.
I have 3 models. Firstly I have a voter which has many votes. Votes is a join table to link the voter and the entry. But when I try to save the votes they are not saving. My models look like this:
class Vote < ActiveRecord::Base
belongs_to :entry
belongs_to :voter
attr_accessible :entry, :voter, :voter_id
class Voter < ActiveRecord::Base
attr_accessible :email_address, :verification_code, :verified, :votes_attributes, :votes
has_many :votes, :class_name => "Vote"
accepts_nested_attributes_for :votes
class Entry < ActiveRecord::Base
attr_accessible :caption, :email_address, :filename
end
I am then my form looks like this:
<%= f.fields_for :votes do |builder| %>
<fieldset>
<%= builder.label :votes, "Vote" %>
<%= collection_select(:votes, :entry_id, Entry.all, :id, :caption, :prompt => 'Please select an Entry') %>
</fieldset>
<% end %>
But the votes are not saving in the database. The response looks like this:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x5f85viIp/KHJKQF7DotaF3MhebARWcaLDKRbcZw/lM=", "voter"=>{"email_address"=>"sadasfd"}, "votes"=>{"entry_id"=>"3"}, "commit"=>"Create Voter"}
So whats going wrong?
Please try
class Voter < ActiveRecord::Base
attr_accessible :email_address, :verification_code, :verified, :votes
has_many :votes, :class_name => "Vote"
attr_accessible :votes_attributes,
accepts_nested_attributes_for :votes
Modify vote_params in VotesController
private
def vote_params
params.require(:vote).permit(:id, :email_address, :verification_code, :verified, votes_attributes: [:id, :name])
end
OK this is weird, I have basically the following classes:
class PriceProfile < ActiveRecord::Base
has_many :prices
has_many :price_profile_date_ranges
attr_accessible :name, :price_profile_date_ranges_attributes
accepts_nested_attributes_for :price_profile_date_ranges
}
class PriceProfileDateRange < ActiveRecord::Base
attr_accessible :end_date, :price_profile_id, :start_date, :prices, :prices_attributes
has_many :prices, :dependent=>:destroy
belongs_to :price_profile
accepts_nested_attributes_for :prices
}
class Price < ActiveRecord::Base
attr_accessible :price_profile_date_range_id, :price_profile_id, :product_id, :value
belongs_to :price_profile
belongs_to :price_profile_date_range
belongs_to :product
}
A price profile defines a pricing scheme for a particular product whose price changes over time. The date ranges over which a price is applied is stored in the price_profile_date_range table and finally the prices table holds all the prices. I'm using the following controller & view to create the form here for setting prices while creating a date range. Basically the form has a start and end date fields and a grid i.e it would have a list of texteboxs against all products to enter the price.
This is the view:
.row
.span9
= simple_form_for(#price_profile_date_range, :class=>'well') do |f|
.form-inputs
= f.input :start_date, :required => true, :as => :string, :input_html =>{:class=>'datepicker'}
= f.input :end_date, :required => true, :as => :string, :input_html =>{:class=>'datepicker'}
= f.input :price_profile_id, :as=>:hidden
%table.table.table-bordered.table-condensed.table-striped
%tr
%td
- #products.each do |product|
%td
=product[:name]
%td
- f.fields_for(:prices) do |price_element|
= price_element.input :value, :class=>'span1'
= price_element.input :price_profile_id, :as=>:hidden
= price_element.input :price_profile_date_range_id, :as=>:hidden
= price_element.input :product_id, :as=>:hidden
.form-actions
= f.button :submit
This isnt exactly the final form - the problem is that the f.fields_for line doesn't seem to execute. In the controller I initialise the #price_profile_date_range object with a set of prices. If I do a raise inspect it shows all the price objects even in the view however the fields_for doesn't execute at all. I'm pretty stuck here real badly.
Try changing the - to a = - sounds silly but maybe that's the problem.
I have the following structure working on my application.
class Foo < ActiveRecord::Base
has_many :examples, :dependent => :destroy
accepts_nested_attributes_for :examples
end
class Example < ActiveRecord::Base
belongs_to :foo
has_many :codes, :dependent => :destroy
accepts_nested_attributes_for :codes, :reject_if => lambda { |a| a[:code].blank? }
end
class Code < ActiveRecord::Base
belongs_to :example
has_many :code_kinds
has_many :kinds, :through => :code_kinds
attr_reader :kind_tokens
def kind_tokens=(ids)
self.kind_ids = ids.split(",")
end
end
class CodeKind < ActiveRecord::Base
belongs_to :code
belongs_to :kind
end
class Kind < ActiveRecord::Base
has_many :code_kinds
has_many :codes, :through => :code_kinds
end
And it's working perfectly for the form with fields_for on create and save.
I'm using kind_tokens as described on RailsCast #258 Token Fields
But on the edit form everything displays perfectly now I should be pre-populating the data in a data-pre attribute on the kind_tokens field inside the nested attributes for code in examples.
The RailsCast say:
<%= f.text_field :author_tokens, "data-pre" => #book.authors.map(&:attributes).to_json %>
But I can't do #foo.examples.codes.kinds.map... because the relation with Foo and examples returns a collection, the same situation with codes.
I'm just using:
<%= f.fields_for :codes do |codes_form| %>
That's inside of
<%= f.fields_for :examples do |examples_form| %>
Now how can I pre-populate the kind for code if I don't have any loop, and everything's done by nested_attributes and fields_for ?
Solved
Everytime you use a
<%= f.fields_for ...
Rails automatically makes a loop so you can have some kind of counter there like:
<%
#ctrEx = 0
#ctrCd = 0
%>
<%= form_for #foo ...
<%= f.fields_for :examples do |examples_form| %>
...
<%= examples_form.fields_for :codes do |codes_form| %>
...
<%= codes_form.text_field :kind_tokens, :class => "tag_matcher", "data-pre" => #foo.examples[#ctrEx].codes[#ctrCd].kinds.map(&:attributes).to_json %>
...
<%#ctrCd +=1%>
<%end%>
...
<%
#ctrEx += 1
#ctrCd = 0
%>
<%end%>
<%end%>
Now you can use your counters in the data-pre like this:
#foo.examples[#ctrEx].codes[#ctrCd].kinds.map(&:attributes).to_json
That's the way i figured it out, but there must be another way.
These are my models:
class Bedommelse < ActiveRecord::Base belongs_to :virksomhed_primary,
:class_name => 'Virksomhed',
:foreign_key => 'virksomhed_id' belongs_to :virksomheds,
:foreign_key => "virksomhed_id"
end
class Bedommelse < ActiveRecord::Base belongs_to :virksomheds,
:foreign_key => "virksomhed_id" belongs_to :freelances,
:foreign_key => "freelance_id"
end
I am trying to display the name of the virksomhed_id not the id itself in the One View (Bedommelse view)
I can show the column virksomhed_id:
<% #bedommelses.each do |bedommelse| %>
<p><%= bedommelse.virksomhed_id</p>
<% end %>
How do I show the name of the virksomhed?
I have tried this but it didn't work.
<% #bedommelses.each do |bedommelse| %>
<p><%= bedommelse.virksomhed.navn </p>
<% end %>
I have found my mistake
I did a fail in the models:
It should be:
belongs_to :virksomhed
not
belongs_to :virksomheds
And the view should be:
<%= #bedommelse.virksomhed.navn %>