Jump to content

The ultimate community for Ruby on Rails developers.


Photo

Multiple instances of the same model in the same form

form timesheet view

  • Please log in to reply
11 replies to this topic

#1 Aydin

Aydin

    Passenger

  • Members
  • 5 posts

Posted 19 October 2013 - 05:23 AM

I'm having trouble creating a form with multiple instances of the same model. My form is for a timesheet application. I have attached a screenshot of what I would like to create.

 

The table that will store the data is called project_activity and contains the following column names:

activity_id PK, project_id, task_id, party_id, activity_hours.

 

The user will only select the party, project and task once. When "Saved", 7 project_activity records should be created. I have attempted to do this through form_for however, multiple party, project and task drop_down menus appear.

 

 

 

Attached Thumbnails

  • Screen Shot 2013-10-19 at 4.04.22 PM.png


#2 rayray

rayray

    Signalman

  • Members
  • 15 posts

Posted 20 October 2013 - 01:18 PM

Could you share some code? What does your form look like?

 

As far as I understand your question, you need a select and option tag like this:

form.select :project_id, options_for_select(Project.all.map {|project| [project.name, project.id]})

And then in the controller you could do something like this:

7.times do
  Activity.create(activity_params)
end

Of course, you shouldn't use exactly this style in production...


I'm Jack's complete lack of ruby knowledge.


#3 Aydin

Aydin

    Passenger

  • Members
  • 5 posts

Posted 21 October 2013 - 10:22 AM

Thanks for replying rayray.

 

Below is my code. The screenshot I provided is the output from my code however, it fails to save any records in the back end.

 

My intention is to have 3 drop down menus (party, project and task) which when selected by the user will be stored in a local variable. This variable will then be captured in a hidden field tag for each activity_hour field displayed so that when the form is saved, 7 project_activity records will be created with the same party, project and task.

 

I haven't attempted this in the code provided because I don't know how to. Is it possible?

 

Thanks for your help.

<h1>Timesheet</h1>

<%= form_for(@project_activity) do |f| %>

	<%= f.collection_select(:party_id, Party.all, :id, :party_name, {:prompt => params[current_party]}, {class: "span2"}) %></br>

	<table class="table">
		<tr>
			<td><%= select_tag 	"project_activity[project_id]", 
						grouped_options_for_select(Project.for_select(@date.strftime("%Y%m%d"))), 
						{include_blank: true, class: "span2"} %></td>
			<td><%= select_tag 	"project_activity[task_id]", 
					        grouped_options_for_select(ProjectTask.for_select(@date.strftime("%Y%m%d"))), 
						{include_blank: true, class: "span2"} %></td>

			<% form_date = @date.beginning_of_week %>
			<%= (@date.beginning_of_week..@date.end_of_week).each do %>
				<%= f.fields_for(@project_activity) do |builder| %>
					<td>
						<%= builder.number_field :activity_hours, :class => 'input-mini' %>
						<%= hidden_field_tag "project_activity[activity_date]", form_date %>
						<% form_date+=1 %>
					</td>
				<% end %>
			<% end %>

		<tr>
			<td><%= f.submit "Save", :class => 'btn btn-primary' %></td>
		</tr>
	</table>

	<% end %>


#4 rayray

rayray

    Signalman

  • Members
  • 15 posts

Posted 21 October 2013 - 03:13 PM

It's a bit confusing... Could you show what the project_activity records should look like in the end , with sample data?

Why is there a date if you choose the project_id and task_id?

 

I'm not a front-end guy but I think mixing a table with a form isn't best practice. Maybe you want to try the Simpleform gem? https://github.com/p...tec/simple_form


I'm Jack's complete lack of ruby knowledge.


#5 stevieing

stevieing

    Dispatcher

  • Members
  • 39 posts

Posted 22 October 2013 - 02:20 PM

You probably need something like this http://railscasts.co...el-form-revised

 

Rayray is right. You shouldn't use tables within forms. It is better to use fieldsets and lists.

 

There is a lot in there that could be abstracted out.

 

For example with @date.strftime("%Y%m%d"). You could add something like Date::DATE_FORMATS[:ymd] = '%Y%m%d' in an initializer and then use @date.to_s(:ymd) in your view. Even better that should be done in a helper or the controller. This way you can reuse it across your application.

 

You would probably be better to use a partial for your nested models. i.e.

 

<%= f.fields_for @project_activity do |builder| %>
    <%= render "my_partial", f: 'builder' %>

<% end %>

 

There are all sorts of other things you could do with your form to make it more Rails like. Views should only be used for presentation so things like assigning variables are best moved elsewhere.

 

Regards

 

Steve.



#6 Aydin

Aydin

    Passenger

  • Members
  • 5 posts

Posted 24 October 2013 - 07:53 AM

Thanks Steve but I have already had a look at the Railscast you posted. That solution doesn't solve my problem because I'm not nesting models. I'm trying to create multiple instances of a single model in a single form but I'm having trouble creating the new and create controller methods as well as the form.

 

Thanks for the tips on how to clean up my view.



#7 stevieing

stevieing

    Dispatcher

  • Members
  • 39 posts

Posted 24 October 2013 - 10:12 AM

In which case there are many options.

 

You could refactor your model to include a has many relationship, you could use Ajax in your form ( a framework like angular.js may be helpful) or there is another Railscast about form objects http://railscasts.co...16-form-objects

 

My first instinct would be to refactor the model but it is difficult to gauge without knowing the architecture.

 

Hope that helps.

 

Steve.



#8 rayray

rayray

    Signalman

  • Members
  • 15 posts

Posted 24 October 2013 - 02:18 PM

You have to provide more information. For example, why do you need 7 records at one time? We need to understand what you're trying to do.


I'm Jack's complete lack of ruby knowledge.


#9 Aydin

Aydin

    Passenger

  • Members
  • 5 posts

Posted 26 October 2013 - 12:58 AM

Sorry, I'll try again.

 

I am trying to create a Timesheet form which tracks the amount of hours a party (user) has spent on a task within a project for a specific week. I have attached a clearer mockup of the form I am attempting to create here http://img9.imagesha...9/6886/12e6.png

 

The table in my database that stores the timesheet information is called "PROJECT_ACTIVITY". This table has foreign keys referencing the "PARTY", "PROJECT" AND "PROJECT_TASK" tables.  The "PARTY" drop-down menu options come from the "PARTY" table, the "PROJECT" from the "PROJECT" table and the "TASK" from the "PROJECT_TASK" table. I have attached a portion of my ERD to display the relationships between these tables here http://img13.imagesh...3/4372/39hn.png

 

One "PROJECT_ACTIVITY" record represents hours worked by a "PARTY" on a specific day for a specific "PROJECT" and "TASK". Most people in my company work on the same "PROJECT" and "TASK" for the entire week so I would like them to be able to select these two options once, and then input the amount of hours they worked for each day of the week. If they worked on multiple projects during the week, I would like the form to have an option of creating another line of input fields through AJAX but that is something I am not looking at creating at the moment. Currently, I would just like to get the basics developed.



#10 rayray

rayray

    Signalman

  • Members
  • 15 posts

Posted 26 October 2013 - 02:29 PM

Ok, this is a much better explanation  :D

 

If you want to create your app exactly like in your mockup, you rely heavily on Javascript. The form has to know the week before you can load the labeled fields for every weekday. And it also has to know the project before it can load the tasks for the project.

 

I think it would be much easier, if you separate in 2 steps:

  1. A form for selecting the week, the party and the project - then submit
  2. A new form with the available tasks for the specific project and the hour text-fields for each day

I'll write more in the next days, cheers


I'm Jack's complete lack of ruby knowledge.


#11 Aydin

Aydin

    Passenger

  • Members
  • 5 posts

Posted 02 November 2013 - 12:08 AM

Thanks rayray.

 

I don't have a problem with step 1 you suggested however, I am struggling with step 2. I'm not sure how to setup the controller or view to output 7 hour text-fields and save all 7 records. Are you able to provide an example?



#12 rayray

rayray

    Signalman

  • Members
  • 15 posts

Posted 05 November 2013 - 10:16 PM

You have to use the parameters that you submit in Step 1, for example: 

def new
  @project = Project.find(params[:id])
  @activities = Array.new(7) { @project.activities.build }
end

Then the view could look like this:

<%= form_for [@project, :activities] do |f| %>
  <% @activities.each do |activity| %>
    <%= fields_for activity do |a| %>
       <%= a.text_field :hours %>
    <% end %>
  <% end %>
<% end %>

And the create action:

def create
  @project = Project.find(params[:id])
  @activities = Activity.create(params[:activities])
end

I'm Jack's complete lack of ruby knowledge.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users