I have to create a form which includes Batches and Samples.
General idea would be Batches having (received:date, group_leader:string, contact_person:string, batch_comment:string and num_of_samples:integer) .
N.B batches have many samples.
now the Samples include ( sample_name, species, sample_type, ini_conc, ini_vol, and sample_comment).
Now as these are of one to many relationships, I have created a form after following many tutorials having a page showing batch detail entry as well as asking for how many samples it involved in each batch. After the user types in (for eg. 3), the form generates three fields having sample details (also including name, species, type, conc, vol, etc.) but I was not able to send these details to the database.
The only thing that updates the database is one sample information.
my view looks something like this :
New sample:
<p><% form_for(sample) do |f| %></p>
<p><% (1..#batch.sample_no).each do |i| -%></p>
<%= f.error_messages %>
<p>
<%= f.hidden_field :batch_id %>
</p>
<p>
<%= f.label :sample_name %><br />
<%= f.text_field :sname %>
</p>
<p>
<%= f.label :organism %><br />
<%= f.text_field :organism, :rows => 2 %>
</p>
<p>
<%= f.label :sample_type %><br />
<%= f.select(:samp_type, %w{ DNA RNA}) %>
</p>
<p>
<%= f.label :ini_conc %><br />
<%= f.text_field :ini_conc %>
</p>
<p>
<%= f.label :ini_vol %><br />
<%= f.text_field :ini_vol %>
</p>
<p>
<%= f.label :storage_space %><br />
<%= f.text_field :storage_space %>
</p>
<p>
<%= f.label :samp_comment %><br />
<%= f.text_area :samp_comment, :rows => 3 %>
</p>
<% end -%>
<p><%= f.submit 'Submit' %></p>
<% end %>
I haven't done anything much with my controller. (in fact I have no idea which controller I should add codes to) meaning I have created two scaffolds, one for batch and one for samples and I have made a partial of the samples_view_new.html.erb and saved it in the batch_view folder which gives me an opportunity to add samples in the show_html.erb of the batch.
my models of batch.rb and sample.rb look some thing like this
<p>class Batch < ActiveRecord::Base</p>
<p>has_many :samples</p>
<p>end</p>
<p>class Sample < ActiveRecord::Base </p>
<p>belongs_to :batch</p>
<p>end</p>
if I understand your requirements correctly, you're searching for nested forms as excellently described by Ryan Bates at railscasts.com
Tutorial 1: Nested Model Form Part 1
Tutorial 2: Nested Model Form Part 2
Here is some more help for you:
In your Bash model
has_many :samples
accepts_nested_attributes_for :samples
Your Bash Controller will have at least 2 actions: new and create
In your new action:
#bash = Bash.build
4.times { #bash.samples.build } # where 4 is the no. of samples, could also be param[:amount] in case you add a preliminary action with a form and an amount field, but I suggest using javascript as described in Tutorial 2 above for better user experience
In the create action:
#bash = Bash.new(params[:bash]) # you now have access to #bash.samples
if #bash.save ...
And finally the "new" view:
<%= form_for #bash do |f| %>
<%= f.text_field :group_leader %> <!-- ... -->
<%= f.fields_for :samples do |builder| %>
<%= builder.text_field :sample_name %> <!-- ... -->
<% end %>
<%= end %>
With this and the tutorials you should now be able to build a killer app for your degree's application. Good luck!
I think I have the solution to the problem...
My main idea was to send multiple rows in the database at once... so just follow this tutorial
http://www.stephenchu.com/2008/03/paramsfu-3-using-fieldsfor-and-index.html
Related
I'm currently following a Ruby on Rails tutorial book and I've noticed that the newer version of Rails is quite a bit different. A couple of given commands were different than described in the book and I've had to look up a few ways on how to fix these things. Right now though, I don't know what's going wrong. I have created a database table products and I'm simply trying to use a form to display some input components etc to create a new product. The book told me to do this:
<h1>New product</h1>
<% form_for(#product) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br />
<%= f.text_area :description, :rows => 6 %>
</p>
<p>
<%= f.label :image_url %><br />
<%= f.text_field :image_url %>
</p>
<p>
<%= f.label :price %><br />
<%= f.text_field :price %>
</p>
<p>
<%= f.submit "Create" %>
</p>
<% end %>
<%= link_to 'Back', products_path %>
However, the view only shows me the New product header and the link to go back. I've already installed a different gem because the f.error_messages apparently wasn't used anymore either. The problem is, the entire form_for part does not show up anything. Can anybody tell me how I am supposed to change this code to get it to show up on the view for creating a new product?
Thanks!
This is what it shows:
You are missing = here <% form_for(#product) do |f| %>. It should be
<%= form_for(#product) do |f| %>
I have following two resources:
Position
JobTitle
And a position belongs_to job title.
In page Position, I create new position, with job_title select and some other selects. I need also create new job_title in this page, instead of choose select variants. So, in fact, or I choose job title in existing base, or create new, and save it for this position.
How can I make this? I looking for answer, and reading docs, but nothing!
You need to use fields_for in your view to send params for two models at a time.
Here's how I would try to solve to problem:
<%= form_for #job_title do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :description %><br />
<%= f.text_field :description %>
</p>
<%= f.fields_for :position do |builder| %>
<p>
<%= builder.label :name %> <br />
<%= builder.text_field :name %>
</p>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>
And then, in your controller, you need to create the association. For more information, you can check out the railscast for nested forms.
I'm trying to put together a rails site that uses a number of models. One is a model called requests that takes in a couple pieces of information associated with essentially a single purchase. The other is a model that collects a number of the requests together under one "order" id.
The problem is, I want the view associated with request to allow for multiple request entries with one submission, and I can't figure that out. As I've currently got it, someone can submit a single request for a single "cut", but I want them to enter a number of requests for a number of cuts on a single page, with a single submission.
My current _form document associated with my view is:
<%= form_for(#request) do |f*| %>
<div class="field">
<%= f.label :cut %><br />
<%= f.text_field :cut %>
</div>
<div class="field">
<%= f.label :lbs %><br />
<%= f.number_field :lbs %>
</div>
<div class="field">
<%= f.label :notes %><br />
<%= f.text_field :notes %>
</div>
<div class="field">
<%= f.label "Order ID" %><br />
<%= f.number_field :order_id %>
</div>
<div class="field">
<%= f.label :status %><br />
<%= f.number_field :status %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Any idea how I can create a form document that allows me to enter several new 'rows' of requests with one submit? Or how to ensure they all have the same order-id?
Thanks.
Try these screencasts from Ryanb, I think they'll get you a long way.
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
My example form
<% form_for #ad do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :ad_type_id %><br />
<%= f.collection_select(:ad_type_id, AdType.all, :id, :name) %>
</p>
<p>
<% #ad.ad_properties.each do |property| %>
<%= property.name %>:
<% f.fields_for :ad_values do |value_field| %>
<%= value_field.text_field :ad_id, :value => #ad.id %>
<%= value_field.text_field :ad_property_id, :value => property.id %>
<%= value_field.text_field :value %>
<% end %><br /><br />
<% end %>
</p>
<p>
<%= f.label :description %><br />
<%= f.text_area :description %>
</p>
<p><%= f.submit %></p>
<% end %>
Explanation:
Ad has many properties. I can add new properties at any time (it's a normal model).
Lets say the Ad is of the type 'hotel'. Then I would add properties like 'stars' and 'breakfast_included'
Then I store each of these properties' values in a separate model.
And all this works fine with my form above.
My problem:
These fields are not validated because I can't know what their names are.
I need to add validations dynamically somehow.
My thought:
#Before the normal validations kick in
def add_validations
self.properties.each do |property|
property.add_validation :whatever #somehow :)
end
end
How could I do this?
Have you tried with polymorphic associations ? That's maybe a cleaner approach.
http://railscasts.com/episodes/154-polymorphic-association
Disclaimer: I've never done this before, so I'm not 100% sure it will work.
But as long as you can get the type of the object you are working with, you can use the Rails constantize method to get the model it references (I'm assuming that if ad can be of type Hotel, then you have a Hotel model). At that point you should probably have the appropriate validations on your Hotel model.
In Rails, how do I generate form labels without symbols that still create correct "for" attributes?
If I take this form:
<% form_for(#thing) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
And alter it to improve the clarity of what's expected in the field:
<% form_for(#thing) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label "What would you like to call your thing?" %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
The for attribute on the label tag would read "thing_What would you like to call your thing?", which obviously destroys its relationship with the intended partner field.
So how do I alter the label text while preserving that relationship?
<%= f.label :name, "What would you like to call your thing?" %>
See label’s documentation (and on APIdock).