How can i associate item with the association. Here an example and here the models
-Customer
-Phone
-PhoneType
Customer Phone PhoneType
Id Id Id
First Number Description
Last Phone_Type_Id
Email isViewed
Password
...
The relationship his has follow
Customer
has_many phone
accepts_nested_attributes_for :phone, allow_destroy: :true
Phone
belongs_to :customer
has_one :phone_type
accepts_nested_attributes_for :phone, allow_destroy: :true
PhoneType
belongs_to :phone
The way my form view work his has follow in
Customer#edit view
I render a general form which consist of other fields and inside of it I have the following code
<%= f.fields_for :phones do |b| %>
<fieldset>
<%= b.label :number %>
<%= b.select :PhoneType %> ## issues is here
<%= b.label :isViewed %>
</fieldset>
<% end %>
Thanks in advance!
try
:phone_type
instead of using camelcase (PhoneType) in the form. Your association in the phone model expects a field called :phone_type so you need to fix the case.
Also, what is being rendered in your views with the way they are now? Are you getting any errors?
So you want go give the user the option to select a phone type by choose a description from the dropdown? You might try something like
<%= select(:phone_type, :phone_type_id, PhoneType.all, :id, :description) %>
Finally, you might want to take a look at the simple form gem....
https://github.com/plataformatec/simple_form/
Related
I have a has_many association between Items and their Components through a table called ComponentItems. ComponentItems contains a column quantity in addition to item_id and component_id. How is it possible to add a number_field to my form that shows the quantity of each component required for an item? The form must contain a number_field for each Item in the database, even if no relationship exists (i.e. #item.component_ids.empty? == true).
class Item < ActiveRecord::Base
has_many :components, through: :component_items
has_many :component_items
end
class Component < Item
has_many :items, through: :component_items
has_many :component_items
end
class ComponentItem < ActiveRecord::Base
belongs_to :item
belongs_to :component
end
I believe I've tried every permutation of model, controller and form_builder possible, except the correct one.
In response to the answer below, here's a form that shows a checkbox and the item code for component items that make up one particular item;
<%= form_for [#item] do |f| %>
<%= f.collection_check_boxes :component_items, Item.active.where.not(sku: #item.sku).sort_by{|n| n.sku}, :id, :sku do |b| %>
<%= b.check_box %> <%= b.label %><br/>
<% end %>
<% end %>
So, ideally I'd replace the check_box with a number_field for quantity. How?
So it seems what I wanted is not so straightforward after all. In the end I opted for using some jQuery for adding extra Components to Items via a separate form. Trying to add/remove components and adjust the quantities was beyond me, so choosing to use separate forms for each user action seemed simpler. It may not be the most user-friendly way of working but it's the best I have.
To edit the quantities I did the following;
<% #item.component_items.each do |x| %>
<%= hidden_field_tag "item[component_items_attributes][][id]", x.id%>
<%= label_tag x.component.sku, x.component.sku.upcase, :class=>"col-md-3 control-label" %>
<%= number_field_tag "item[component_items_attributes][][quantity]", x.quantity, :class=>"col-md-5"%>
<%end %>
and ensured the Item model accepted nested attributes for component_items. Finally, add the nested params array for multiple component_items to items_controller.rb...
def item_params
params.require(:item).permit(
:component_items_attributes =>[:component_id, :item_id, :quantity, :id]
)
end
Note I didn't use fields_for which seemed to generate an extra component_items_attributes array that didn't make any sense at all.
This should work:
#item.components.to_a.sum(&:quantity)
This will throw an error if quantity on some component is nil, so you may try like this to avoid errors:
#item.components.to_a.map(&:quantity).compact.sum
UPDATE
<% #item.component_items.each do |component_item| %>
<%= form_for(component_item) do |f| %>
<div class="field">
<%= f.label :quantity, 'Quantity' %><br />
<%= f.number_field :quantity %>
</div>
<% end %>
<% end %>
I have three Models:
class Question < ActiveRecord::Base
has_many :factor_questions
has_many :bigfivefactors, through: :factor_questions
accepts_nested_attributes_for :factor_questions
accepts_nested_attributes_for :bigfivefactors
end
class Bigfivefactor < ActiveRecord::Base
has_many :factor_questions
has_many :questions, through: :factor_questions
end
and my join-table, which holds not only the bigfivefactor_id and question_id but another integer-colum value.
class FactorQuestion < ActiveRecord::Base
belongs_to :bigfivefactor
belongs_to :question
end
Creating an new Question works fine, using in my _form.html.erb
<%= form_for(#question) do |f| %>
<div class="field">
<%= f.label :questiontext %><br>
<%= f.text_field :questiontext %>
</div>
<%= f.collection_check_boxes :bigfivefactor_ids, Bigfivefactor.all, :id, :name do |cb| %>
<p><%= cb.check_box + cb.text %></p>
<% end %>
This let's me check or uncheck as many bigfivefactors as i want.
But, as i mentioned before, the join model also holds a value.
Question:
How can I add a text-field next to each check-box to add/edit the 'value' on the fly?
For better understanding, i added an image
In the console, i was able to basically do this:
q= Question.create(questiontext: "A new Question")
b5 = Bigfivefactor.create(name: "Neuroticism")
q.bigfivefactors << FactorQuestion.create(question: q, bigfivefactor: b5, value: 10)
I also found out to edit my questions_controller:
def new
#question = Question.new
#question.factor_questions.build
end
But i have no idea how to put that into my view.
Thank you so much for your help!
Big Five Factors model considerations
It looks like your Bigfivefactors are not supposed to be modified with each update to question. I'm actually assuming these will be CMS controlled fields (such that an admin defines them). If that is the case, remove the accepts_nested_attributes for the bigfivefactors in the questions model. This is going to allow param injection that will change the behavior sitewide. You want to be able to link to the existing bigfivefactors, so #question.factor_questions.first.bigfivefactor.name is the label and #question.factor_questions.first.value is the value. Notice, these exist on different 'planes' of the object model, so there wont be much magic we can do here.
Parameters
In order to pass the nested attributes that you are looking for the paramater needs to look like this:
params = {
question: {
questiontext: "What is the average air speed velocity of a sparrow?",
factor_questions_attributes: [
{ bigfivefactor_id: 1, value: 10 },
{ bigfivefactor_id: 2, value: 5 } ]
}
}
Once we have paramaters that look like that, running Question.create(params[:question]) will create the Question and the associated #question.factor_questions. In order to create paramaters like that, we need html form checkbox element with a name "question[factor_questions_attributes][0][bigfivefactor_id]" and a value of "1", then a text box with a name of "question[factor_question_attributes][0][value]"
Api: nested_attributes_for has_many
View
Here's a stab at the view you need using fields_for to build the nested attributes through the fields for helper.
<%= f.fields_for :factor_questions do |factors| %>
<%= factors.collection_check_boxes( :bigfivefactor_id, Bigfivefactor.all, :id, :name) do |cb| %>
<p><%= cb.check_box + cb.text %><%= factors.text_field :value %></p>
<% end %>
<% end %>
API: fields_for
I'm not sure exactly how it all comes together in the view. You may not be able to use the built in helpers. You may need to create your own collection helper. #question.factor_questions. Like:
<%= f.fields_for :factor_questions do |factors| %>
<%= factors.check_box :_destroy, {checked => factors.object.persisted?}, '0','1' %> # display all existing checked boxes in form
<%= factors.label :_destroy, factors.object.bigfivefactor.name %>
<%= factors.text_box :value %>
<%= (Bigfivefactor.all - #question.bigfivefactors).each do |bff| %>
<%= factors.check_box bff.id + bff.name %><%= factors.text_field :value %></p> # add check boxes that aren't currently checked
<% end %>
<% end %>
I honestly know that this isn't functional as is. I hope the insight about the paramters help, but without access to an actual rails console, I doubt I can create code that accomplishes what you are looking for. Here's a helpful link: Site point does Complex nested queries
Hi im using Nested_forms gem for a app, everything is working fine.. Im following the documentation here ...
My form is saving data to database, i can create infinite number of extra fields as i require.
The only problem is when i want to populate the list for example to Edit, then i canĀ“t populate again the list with all the values the user have previously selected, just the 1st value is there , the 2nds select box that should appear, appear transparent.. i leave an image , because english is not my lenguage y probably suck describing it
EDIT: I think the problem is on the loop , because first time when you submit it look like this..
And after saving, and lunching the form again to edit. this is what you get.
Here is the code in there.
<div id="nacionalidad">
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }.sort_by {|label,code| label}, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
</div>
And the model
class Citizen < ActiveRecord::Base
attr_accessible :country_id
belongs_to :player
belongs_to :country
end
You might be going about this the wrong way. In my opinion it's much easier to use multiple-select fields and has_many relations. Then everything just works magically!
Form:
<%= select_tag :countries, options_from_collection_for_select(Country.all, 'id', 'name'), :multiple => true %>
Model:
class Citizen < ActiveRecord::Base
attr_accessible :country_id
belongs_to :player
has_many :countries
end
And then if you'd like, you can use another javascript library to make your multiselects more user-friendly:
Select2: http://ivaynberg.github.io/select2/
ChosenJS: http://harvesthq.github.io/chosen/
I am working with a rails app and have begun to work on a search function using metasearch but I am having troubles getting the correct method for the search.
For example I have a model (Proposal) that has a field cost.
..model/proposal.rb
class Proposal < ActiveRecord::Base
belongs_to :user
has_many :users, :through => :invitations
attr_accessible :cost, :user_id
For which this code works fine with meta search
..views/homes/live_requests.html.erb
<%= form_for #search, :url => "/live_requests", :html => {:method => :get} do |
<%= f.label :cost_greater_than %>
<%= f.text_field :cost_greater_than %><br />
<!-- etc... -->
<%= f.submit %>
Yet with a more complicated association I can not manage to get the meta search path correct.
I am trying to search over:
Proposal.last.user.suburb.name #Returns the name of the suburb as expected
I have tried many associations but cannot find the right one.
Proposal has a user_id field which maps to user
So Proposal.user returns a User
User then has a suburb_id which returns a suburb
Suburb has a field called name which returns a string
How would I work this into a metasearch form?
<%= f.text_field :user_user_suburb_name %>
or
<%= f.text_field :user_id_suburb_id_name %>
I cannot come to a solid conclusion.
Thanks for your help in advance.
Was simply following the correct names as declared by the models.
Ie. in the model above, ensuring that it was User, not users etc.
Hello I have a model named Client which has nested models called Receiver and Receipt.Basically a client donate money to a receiver or many receivers, and that gift appear in a receipt.
model/client.rb
class Client < ActiveRecord::Base
has_many :receivers
has_many :receipts
accepts_nested_attributes_for :receivers
accepts_nested_attributes_for :receipts
end
views/client/_form.html.erb
<%= simple_form_for #client do |f| %>
<%= f.input :name %>
<%= f.input :input %>
<%= f.input :suscribtion_number %>
<%= simple_fields_for :orders do |o| %>
<%= o.input :name %>
<% end %>
<%= f.button :submit %>
<% end %>
Matter fact how can I dynamically transfer a client "input" to
1- an oder's "amount"(attribute)
2- and to a receipt's "amount"(attribute)
You can simply do #receipt.amount = #client.amount. However, the better way to model this would be to have a Donation model with an amount attribute. Then, link clients and receivers to the donation.
The donation model would probably replace your receipt model. When you need to compute how much a client has donated, simply sum all the associated donation amounts.
By modeling the donation, you won't need to worry about keeping multiple copies of the same information (i.e. the donation amount) in sync. Having multiple copies of the same information is a bad idea, generally speaking.