One Submit button with multiple forms - ruby-on-rails

I'm trying to create a scoring App. Since I'm new to StackOverflow I can't upload the screen shots but here are screen shot links
Now it looks like this.
This is what I want it to be.
Here are the models involve in the view. Just click the next picture = the last picture in the Photostream (again StackOverflow won't allow me to post more than 3 hyperlinks).
This view above is from: localhost/matchdays/4/matches/new
The relationship would look like this:
A Matchday has_many matches.
A Match has_many games (maximum of 3, but for now we'll stick with 1). We will update the score attribute.
A Game has_many pairs (maximum 2).
My question is:
How do you code in the MatchesController (when the user hit Start) to create a game with 2 pairs and each pair has its own score (which is an attribute in the Game model)?
How do you loop in the view to add another Game(Score attribute) and Pair form that belongs to the Match (in this case Match 10)? Just like in the screen shot 2 above.
Matches Controller:
def new
#matchday = Matchday.last
#match = Match.new()
#match.number = match_numbering
#pairs = Pair.all
#matchday.best_of.times { #match.games.build }
end
def create
#match = Match.new(params[:match])
#matchday = Matchday.last
#match.number = match_numbering
if #match.save
#matchday.matches << #match
flash[:success] = "Match recorded"
redirect_to matchdays_path
else
#title = "Record Match"
render 'new'
end
end
/views/matches/new:
<h1>Match <%= #match.number %> of Matchday <%= #matchday.number %> details</h1>
<%= form_for #match, :url => {:action => 'create', :id => #match.id } do |p| %>
<%= render 'shared/error_messages', :object => p.object %>
<%= render :partial => 'match_form', :locals => {:p => p} %>
<% for game in #match.games %>
<%= fields_for :games, game do |game_form| %>
<p>
Score: <%= game_form.text_field :score, :size => 2 %>
</p>
<p>
Pair: <%= select(#pairs, :pair_id,Pair.all.collect{|p| [p.name]}) %>
</p>
<% end %>
<% end %>
<div class = "action_links">
<p> <%= link_to "Cancel", matchdays_path, :class => "cancel" %> |
<%= p.submit "Start" %></p>
</div>
<% end %>
I think the looping must be put some where in the for loop, but not sure how to implement it. Plus my fields_for and select form might might not be correct... much to learn :)

All I had to do was add this line to the Match.rb
has_many :games
accepts_nested_attributes_for :games, :allow_destroy => true

Related

Create multiple records with a loop in Rails

I have a class Shift and a form to create a new shift. I want to be able to create many shifts at once, back-to-back so that in the form I only have to choose a date and a start time and how many shift should be created. A shift is 30 minutes long.
I now have a custom controller method that calls the create method within a loop determined by the param :block that the user chooses. I have now stopped getting error messages, but it turn I don't know what happens when I submit the form, which seems to be nothing. My question is: how can I modify my create_block method so that it does what I want?
Shifts_controller:
def create
#shift = Shift.new(shift_params)
if #shift.save
#redirect_to shifts_url
else
render 'new'
end
end
def create_block
start = params[:start_time]
stop = params[:start_time] + 30.minutes
block = params[:block]
for number in 1..block do
Shift.create(date:params[:date], start_time:start, stop_time:stop)
start = stop
stop = stop + 30.minutes
end
redirect_to shifts_url
end
_form.html.erb
<%= form_for #shift, :url => create_block_path(#shift) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.label :Datum %>
<%= f.date_select :date %>
</div>
<br>
<div class="field">
<%= f.label :Börjar %>
<%= f.time_select :start_time, {minute_step: 30} %>
</div>
<br>
<div>
<%= f.label :Antal %>
<%= f.select :block, options_for_select(1..10) %>
</div>
<br>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
routes.rb
resources :shifts do
member do
patch 'book/' => 'shifts#book', as: 'book'
patch 'un_book/' => 'shifts#un_book', as: 'un_book'
end
end
get 'shifts/:id/book' => 'shifts#book'
get 'shifts/:id/un_book' => 'shifts#un_book'
match '/shifts/new' => 'shifts#new', as: 'create_block', via: [:post]
Your routes are routing the create_block action to ShiftsController#new. You need to route it to ShiftsController#create_block.
Try:
resources :shifts do
member do
patch 'book/' => 'shifts#book', as: 'book'
patch 'un_book/' => 'shifts#un_book', as: 'un_book'
end
collection do
post 'create_block' => 'shifts#create_block', as: 'create_block'
end
end
get 'shifts/:id/book' => 'shifts#book'
get 'shifts/:id/un_book' => 'shifts#un_book'

New model insert overwriting others

I have a rails application where I have two models called Column and Row:
Column:
has_many :rows
accepts_nested_attributes_for :rows, :reject_if => lambda { |b| b[:data].blank? }
Row:
belongs_to :column
And the form:
<%= form_for [#table, #row] do |f| %>
<% #columns.each do |column| %>
<%= f.label :data %><br>
<%= f.text_area :data %>
<% end %>
<%= f.submit %>
<% end %>
and my create action in the controller:
#row = Row.new(row_params)
if #row.save
redirect_to table_rows_path, notice: 'row was successfully created.'
else
render action: 'new'
end
and my new action:
#columns = Column.where(:table_id => #table.id)
#row = Row.new(id: #table.id)
So I have two problems. The first is if I have say two columns, so there will be two textfields on the new row page, and I enter "Test" in the first text field and "Another Test" in the second. The only thing that is getting saved is the second. The first one saves "Another Test" instead of "Test".
Also, how can I get the row (which belongs to a column) to save a column_id inside each row?
Thanks for all help!
You are setting the new Row's id to the #table.id. Take that out; you never need to create a new .id. Then use column_id: params[:column_id] to link them up.

Nested routes form is performing a get request for the index action instead of the create action

I have an app and I have nested routes like so
resources :teams, shallow: true do
resources :texts
resources :translations
end
here is my app/texts.show.html.erb.My app has texts and each text has a translation and each translation belongs to a text.When I click on a text I am taken to the texts show page where I have a form for a translator.The translator can translate the text.Each translation and text belongs to a team so that I can show specific texts and translations for specific teams.However the form below seems to be doing a get request for the index action.That is the error I am getting and I can't figure out why.Maybe something very obvious I am missing.
<% if current_user.translator %>
<%= form_for [#team, #translation] do |f| %>
<%= f.text_area :translation_text, :placeholder => 'Çeviri' %>
<%= f.hidden_field :text_id, :value => params[:id] %>
<%= f.submit 'Çevir', class: 'btn btn-primary' %>
<%end%>
<%end%>
Here is my translations_controller.rb file
def create
team = Team.find(params[:team_id])
#translation = team.translations.new(translation_params)
#translation.user_id = current_user.id
if #translation.save
redirect_to request.original_url, success: 'Çeviri tamalandı'
else
redirect_to request.original_url, danger: 'Çeviri sırasında sorun oluştu lütfen tekrar dene'
end
end
private
def translation_params
params.require(:translation).permit(:team_id, :text_id, :translation_text)
end
Could the problem be that I am in texts#show and am doing something wrong with the form?

Why does this select field appear multiple times in my Rails form?

I've got a Rails application that is using nested forms. Details follow and I tried this solution (Rails 3 Nested Models unknown attribute Error), but for some reason, the field is repeating multiple times instead of listing and saving the options correctly. Thanks in advance for your help!
Model information for Newsavedmaps
has_many :waypoints, :dependent => :destroy
accepts_nested_attributes_for :waypoints
Newsavedmap_controller
def new
#newsavedmap = Newsavedmap.new
waypoint = #newsavedmap.waypoints.build
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #newsavedmap }
end
end
def edit
#newsavedmap = Newsavedmap.find(params[:id])
if #newsavedmap.itinerary.user_id == current_user.id
respond_to do |format|
format.html # edit.html.erb
format.xml { render :xml => #activity }
end
else
redirect_to '/'
end
end
Maptry View
<% form_for #newsavedmap, :html=>{:id=>'createaMap'} do |f| %>
<%= f.error_messages %>
<% f.fields_for :waypoint do |w| %>
<%= w.select :waypointaddress, options_for_select(Waypoint.find(:all, :conditions => {:newsavedmap_id => params[:newsavedmap_id]}).collect {|wp| [wp.waypointaddress, wp.waypointaddress] }), {:include_blank => true}, {:multiple => true, :class => "mobile-waypoints-remove", :id =>"waypoints"} %>
<% end %>
<% end %>
When I use the above code, my form works correctly, but submitting it gives me this error:
UnknownAttributeError (unknown attribute: waypoint)
When I change ":waypoint do |w|" to ":waypoints do |w|" in the view, the select field disappears when the user is creating a new record, and in the edit view, the select field appears several times (however many waypoints the user saved in the record.)
How can I get this form field to work properly?
EDIT 1
Here is my latest attempt. For new records, the select field does not appear. However, in the edit view, the select field appears multiple times. This is a Rails 2 application, FYI. Taking a cue from the comments, I used a collection_select approach (not collection_for_select because I couldn't find documentation for that.) Again, I appreciate your help!
<% f.fields_for :waypoints do |w| %>
<%= w.collection_select( :waypointaddress, #newsavedmap.waypoints, :waypointaddress, :waypointaddress, {:include_blank => true}, {:id =>"waypoints"} ) %>
<% end %>
Your form has the following problems.
Use f.fields_for :waypoints since the argument needs to match the name of the association.
Use collection_select rather than select, since you have an ActiveRecord model behind that field.
So, taking that into account, you could try this for your form:
<% form_for #newsavedmap, :html => { :id => 'createaMap' } do |f| %>
<%= f.error_messages %>
<% f.fields_for :waypoints do |w| %>
<%= w.collection_for_select :waypoint, :waypointaddress, #newsavedmap.waypoints, :waypointaddress, :waypointaddress, { :include_blank => true }, { :multiple => true, :class => "mobile-waypoints-remove", :id =>"waypoints" } %>
<% end %>
<% end %>
The API for collection_select is a bit tricky to get right. I usually need a few attempts as well. This previous SO question may help clear things up: Can someone explain collection_select to me in clear, simple terms?

Rendering form in a model: undefined method `host_with_port' for nil:NilClass

I'm rendering a partial containing a form in a model.
Well that is may be not the most obvious thing to do but still: that is what I'm trying.
Rationale:
Let me first motivate why I'm doing it (so as if you have suggestions of doing another way, please feel free):
I'm building a simple messaging functionality for the users of my app so that when they need to perform an action, they are notified through a message and the message contains the data and the actions to be performed.
An example: users are receiving invitation to join a given group. The invitation contains the name of the owner of the group, the name of the group and two buttons to accept or ignore the invitation.
The code:
Here is the message model:
class Message < ActiveRecord::Base
def self.group_invitation(group, user)
#m=Message.new({
:status => :unread,
:from_user_id => group.owner.id,
:to_user_id => user.id,
:type => :group_invitation,
:title => "Invitation to the group: #{group.name}.",
:message => ActionController::Base.new.send(:render_to_string,
:partial => 'messages/group_invitation',
:locals => {:group => group,
:user => user}
)
})
#m.save!
end
end
Here is the partial I'm rendering in the model (i.e. 'messages/group_invitation'):
<div>
<h1> Invitation to <%= group.name %> </h1>
<p>
Hello <%= user.name %>,
</p>
<p>
You have been invited by <%= group.owner.name %> to join the group
<%= group.name %>.
</p>
</div>
<div>
Please take one of the following action:
<br/>
<%= m= group.memberships.find_by_user_id(user.id)
m.status = :validated
render 'memberships/form', :membership => m, :method =>
:put, :label => "Accept" %>
<br/>
<%= render 'memberships/form', :membership => m, :method =>
:delete, :label => "Ignore" %>
</div>
where the 'membership/form' partial is:
<%= form_for membership, :html => {:method => method} do |f| %>
<%= f.hidden_field :group_id %>
<%= f.hidden_field :user_id %>
<%= f.hidden_field :status %>
<%= f.submit :value => label %>
<% end %>
The user has a membership to the group that is created when the invitation is sent with the status 'invited'. The user will receive an internal message with in it the ability to update the membership to the 'validated' status.
Without the form the invitation is correctly produced but with the form, I get the following error at the first line of the 'membership/form' partial:
undefined method `host_with_port' for nil:NilClass
I assume I have to include/require the definition of the urlherlpers somewhere in order the render produce the correct paths etc. But my attempts to do so did not yield any success.
So if there is some clever guy looking at it, may be he will be so kind to give me some ideas to solve this.
Many thank in anticipation

Resources