Rendering one models 'edit form' in anothers 'index view' - ruby-on-rails

I have two models, Teams and Players. On the teams index page I have a list of players that aren't assigned to a team. I'm trying to make a button so that I can click on one of the players with no team and have the 'edit form' of this player show up on the team index page.
This is my current team#index:
= link_to 'New Team', new_team_path
= link_to 'New Player', new_player_path
#teamLists
- #teams.each do |team|
.team
.teamtitle
.teamname
= link_to truncate(team.name, length: 18), edit_team_path(team)
.teammoney
= number_to_currency(team.adjust_money, precision: 0)
%table
%tr.tableheading
%th.namecolumn Player
%th.poscolumn Pos
%th.pricecolumn $
-team.players.each do |player|
%tr
%td.namecolumn= player.name
%td.poscolumn= player.position
%td.pricecolumn= player.price
-(1..(10-team.players.length)).each do |x|
%tr
%td ---
=render template: 'players/edit'
=render 'players/playerlist'
and this is my player#edit
%h1 Nominated Player
= render 'players/form'
= link_to 'Show', #player
= link_to 'Back', players_path
and the players/form
<%= form_for(#player) do |f| %>
<% if #player.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#player.errors.count, "error") %> prohibited this player from being saved:</h2>
<ul>
<% #player.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :position %><br />
<%= f.text_field :position %>
</div>
<div class="field">
<%= f.label :price %><br />
<%= f.number_field :price %>
</div>
<div class="field">
<%= f.label :team_id %><br />
<%= f.select :team_id, Team.all.map { |team| [team.name, team.id] }, { :include_blank => true } %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
At the moment I get this error 'undefined method `model_name' for NilClass:Class' I think its because the form doesn't have access to #player which is defined in the players edit action. Is there a way I can get this to work somehow?

You can reference any partial from another view page, and that's fine. However, like in your case, if that partial you require needs some instance variables (like #player) you'll have to either: A) declare it in the controller of Teams, or B) pass it in to the partial.
So for A), in your Teams controller for action index, just add #player = Player.new or whatever you need it to be.
For B), do:
render :partial => "my_partial", :locals => {:player => Player.new}

Related

transfer IDs for a booking

I am trying to create a booking system in ruby on rails, I want a student to book an instructor. I have used devise and created separate models, instructor and student. When a student is logged in, they are able to pick their instructor which is listed, and press 'Book a lesson' both their IDs are transferred to the lesson new form.
I am having two problems, the button to transfer the chosen instructors ID and the student who is signed in ID, to the lessons new page, for the student to book a lesson time and date.
Instructor#index
<% #instructors.each do |instructor| %>
<%=instructor.id%> : <%= instructor.email %>
<%#= button_to 'Book a lesson', new_lesson_path(instructor_id: instructor) %>
<%= link_to 'Book a Lesson', {controller: :lesson, :action => :new, :instructor_id => #instructor.id} %>
<% end %>
Lessons Controller
# GET /lessons/new
def new
# #lesson = Lesson.new
#instructor = Instructor.find(params[:instructor_id])
#lesson = Lesson.new(student_id: Student.find(session[:student_id]).id)
#lesson.instructor_id = #instructor.id
end
lesson FORM new
<%= form_for(#lesson) do |f| %>
<div class="main-title"> New Lesson for "<%= #lesson.instructor.email %> "</div>
<%= f.hidden_field :instructor_id %>
<%= f.hidden_field :student_id %>
<div class="field">
<%= f.label :lesson_date %><br>
<%= f.date_select :lesson_date %>
</div>
<div class="field">
<%= f.label :lesson_start_time %><br>
<%= f.time_select :lesson_start_time %>
</div>
<div class="field">
<%= f.label :lesson_end_time %><br>
<%= f.time_select :lesson_end_time %>
</div>
<div class="actions">
<%= f.submit "Add a lesson" %>
</div>
<% end %>
enter image description here

How do I use select_year with form_for?

I have a form as follows:
<%= form_for(#car, :html => {:class => 'form-horizontal' }) do |f| %>
<% if #car.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#car.errors.count, "error") %> prohibited this car from being saved</h2>
<ul>
<% #car.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :price %><br />
<%= f.text_field :price %>
</div>
<div class="field">
<%= f.label :model_year %><br />
<% %>
<% end %>
</div>
I want to have a collection select for the model year starting 100 years back and going to a year in the future. I have tried
<%= f.select_year :model_year%>
but it says that select_year is not a valid method. Tried
<%= f.date :model_year, :discard_month => true %>
also to no avail. Any thoughts?
select_year is a helper that generates a full select tag with options. Since you're using form_for instead of form_tag, you'll want to use a helper that can be called on a form builder object.
<%= f.select :model_year, (Time.zone.now.year - 100)..(Time.zone.now.year + 1) %>
Reference: http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-select_year

Rails: How to make a form post to another controller action

I know you are usually supposed to use the linking between new/create and edit/update in rails, but I have a case where I need something else. Is there anyway I can achieve this same connection?
I have a form for a model and I want it to post the data (similar to how a new view, post to the create action).
Here is my form
<div id="new-job">
<%= form_for(#job) do |f| %>
<% if #job.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#job.errors.count, "error") %> prohibited this job from being saved:</h2>
<ul>
<% #job.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :location %><br />
<%= f.text_field :location %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit "create job", id: "submit-job", class: "button small radius" %>
<%= link_to "go back", jobs_path, class: "button small radius secondary" %>
<div id="new-job-errors"> </div>
</div>
<% end %>
</div>
Use the :url option.
= form_for #job, :url => company_path, :html => { :method => :post/:put }

Select tag rails

I have a view where I need to show a list of pages (I have a model called Page) and then i need the id of the selected page
I have this code in the view
مهمة جديدة
: <%= form_for :task, :url => {:action=>"create", :controller=>"tasks"}, :html => {:class :
=> "nifty_form"} do |f| %>
<% if #task.errors.any? %>
<div id="error_explanation">
<h2>: عذرا لم نستطع استكمال طلبك</h2>
<ul>
<% #task.errors.full_messages.each do |msg| %>
<li style="color:red;"><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label "اسم المهمة" %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label "وصف المهمة" %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<button><%= link_to 'العودة الى قائمة المهام', project_tasks_path %></button>
<%= f.submit "مهمة جديدة"%>
</div>
<%= select_tag(:page, options_for_select(['a',1])) %>
<% end %>
#pageslist is a 2d array of the form [['pagename', 1], ..]
The question is how can i access the page_id of the selected page in the controller ?
I tried params[:p_id] but it is not working any help please?
This is what I have in the controller:
#task = Project.find(params[:project_id]).tasks.new(params[:task])
#task.update_attributes({:page_id => params[:p_id]})
Assuming that #pagelist is in a format as you described, then in your view:
<%= select_tag(:page, options_for_select( #pagelist )) %>
You had missed it in your example, and provided only 1d array for options_for_select.
With such prepared view your create action will receive page id in:
params[:page]
it's because you had passed :page as a first argument for select_tag.

Rails with AngularJS calculations over nested forms

I have a Rails 3.2.8 app in which I'm applying some AngularJS for calculations dynamically within a form.
I have a basic test application which maps an investor to multiple houses and each house has a cost and a value in which I would like to total at the end.
Here is my form
<div ng-controller="InvestorCtrl">
<%= form_for(#investor) do |f| %>
<% if #investor.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#investor.errors.count, "error") %> prohibited this investor from being saved:</h2>
<ul>
<% #investor.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<% i = 0 %>
<%= f.fields_for :houses do |builder| %>
<%= builder.label :address %>
<%= builder.text_field :address %>
<%= builder.label :suburb %>
<%= builder.text_field :suburb %>
<%= builder.label :cost %>
<%= builder.text_field :cost, "ng-model" => "timesheets[#{i}].cost", "ng-change" => "calc_cost()" %>
<%= builder.label :value %>
<%= builder.text_field :value, "ng-model" => "timesheets[#{i}].value" %>
<% i = i + 1 %>
<% end %>
<div class="field">
<%= f.label :total_cost %>
<%= f.number_field :total_cost, "ng-model" => "total_cost" %>
</div>
<div class="field">
<%= f.label :total_value %>
<%= f.number_field :total_value, "ng-model" => "total_value" %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
</div>
Here is the angularjs coffeescript I'm using
$ (event) ->
app = angular.module "investor", []
app.controller("InvestorCtrl", ["$scope", ($scope) ->
$scope.timesheets = [
{ cost: 295000, value: 450000 },
{ cost: 600000, value: 620000 },
{ cost: 1000000, value: 900000 },
]
$scope.calc_cost = ->
total = 0
for ts in $scope.timesheets
total = total + ts.cost
$scope.total_cost = total
$scope.calc_cost()
])
angular.bootstrap document, ['investor']
When I load a new form I'm building three houses in the controller like so:
def new
#investor = Investor.new
3.times { #investor.houses.build }
respond_to do |format|
format.html # new.html.erb
format.json { render json: #investor }
end
end
The total cost is calculated correctly when going to a new form, however when I change any of the houses 'cost' values the 'total_cost' field is set to blank.
Am I binding correctly?
Is there an easier way to bind nested forms using AngularJS with Rails templates?
At the moment I'm just trying to get a sum of houses 'cost' value into the 'total_cost' field using AngularJS.
I managed to find my problem using the great debugging tool called 'batarang'
https://github.com/angular/angularjs-batarang
I just had to parseInt the strings:
total = parseInt(total) + parseInt(ts.cost)
Following (simplified code) is what I would do:
In html:
<input ng-model="cost1"/><br>
<input ng-model="cost2"/><br>
total: {{ total_cost() }}
In controller:
$scope.total_cost = function() {
return $scope.cost1 + $scope.cost2;
}
PS: I do not know how one should ballance between RAILS and angularjs, but I would use ng-repeat for putting 3 forms. I think code would be cleaner in that way.

Resources