Submitting multiple rows into a database using a single form - ruby-on-rails

I've created a rails app where a user chooses their preference between different vegetables. The database is formatted as follows:
Prefid (key)
Userid
veg1
veg2
preference
The form follows a format --
<%= form_for :pick do |f| %>
<%= f.collection_select( :id, Players.all, :id, :name) %>
<%= f.radio_button(pref.id, veg.veg1) %>
<%= f.radio_button(pref.id, veg.veg2) %>
<%= f.submit %>
<% end %>
Right now, when the form is submitted, I have this as my create method --
def create
#prefs = Prefs.new()
#prefs[:player_id] = post_params[:id]
post_params.delete(:id)
post_params.each do |key, value|
#prefs.games_id = key
#prefs.pick = value
#prefs.save
end
redirect_to #picks
end
This method doesn't work. It only submits the first pick into the database. I've read a few different ways to do this, but none of them really follow the same format as my application.

Related

Passing value of selected radio button in Rails

I'm working on an app in Rails that has teacher and student users. I want to list all the users that belong to a teacher and then let the teacher select a student to send a message to. I have a message model that has :content and :user_id for params. I want to set the :user_id based on the student selected. Here is my code:
<% #students = Student.all %>
<% #students.each do |student| %>
<% if student[:teacher_id] == #current_user.id %>
<%= radio_button 'student', 'id', student.id %>
<%= student.name %>
<% #current_student = Student.find(student.id) %>
<% end %>
<% end %>
<%= form_for Message.new do |f| %>
<%= f.text_area :content, class: 'messageTextarea' %> <br>
<%= f.hidden_field :user_id, :value => #current_student.id %>
<%= f.submit %>
<% end %>
So, I am looping through all students and printing those that have the same ID as the current user (the teacher) with a radio button. The radio button's value is the student's id. Then I want to pass that value to the :user_id of the message so it will then be retrievable for the student's view.
Currently, this code always passes in the value of the last student listed rather than the student selected. How can I change
<% #current_student = Student.find(student.id) %>
to find the student selected rather than the last one?
I did test this code using
<%= f.hidden_field :user_id, :value => #current_user.id %>
and that did work, but I don't want the current_user's id, of course. Thanks for any help!
If you want one form with radio buttons for the students, You gonna need a little bit JavaScript(Or Jquery), All you have to do is to put a listener on these radio button and when user click on one of them you change the hidden input of user_id name.
User example in this link will help you to put listener on a bunch of radio buttons and change another field value, it will be something like this:
$('input[type=radio][name=student[id]]').change(function() {
$('#user_id').val($(this).val());
});
all you have to do is to make sure of name=student[id] and #user_id, if you used this approach you won't need this line anymore:
<% #current_student = Student.find(student.id) %>
Hope it works.

Ruby on Rails access whole params hash

I have an application that deals with user rotas - and I'm currently adding the ability for admin approvals. If the user updates their own rota the params hash looks something like:
Parameters: {id:1, role_id: 1, team_id:1, rota: [startDate: 01/01/2014, endDate:02/02/2014]}
and these are submitted using a form with:
<%= form_for [#team,#role,#rota] do |f| %>
form code
<% end %>
We need to access the attributes outside the rota: object but currently can't find a way to as:
params.require requires you to pass an object in.
My team members have decided to add hidden fields to submit the attributes within the rota object but that seems redundant seeing as they are quite clearly there, we just can't find a way to access them, and ideas?
I was talking about something like
def user_rota_params
params.require(:user)
.permit(:role_id, :team_id, :rota => [:startDate, :endDate])
end
Then, for your nested attributes you could use fields_for.
Your form, thus, should look something this (omitting labels and keeping it basic):
<%= form_for #user do |f| %>
<%= f.text_field :role_id %>
<%= f.text_field :team_id %>
<%= f.fields_for :rota do |ff| %>
<%= ff.date_field :startDate %>
<%= ff.date_field :endDate %>
<% end %>
<% end %>

Disable autopopulate of select fields with database values in rails 4 edit form

I'm running Rails 4.1 and I have an edit form with some values in it, I don't mind other fields on the form being autopopulated from database values, Rails does that nicely. But I want to disable the autopopulation of one field. Is that possible?
I'm doing the standard Rails form_for, everything works I just do not want one of the fields to autopopulate. I do not want to set the value as blank or "" because it would overwrite the database.
Any suggestions?
edit.html.erb
<%= form_for #object do |f| %>
<% f.text_field :property %> #autopopulate from database
<% f.text_field :property2 %> # I do not want to autopopulate.
<% f.submit 'Submit %>
<% end %>
Clear the attribute before rendering a form.
Here's what it would look like in the view:
<% #object.property2.clear %> # set attribute to an empty string
<%= form_for #object do |f| %>
<% f.text_field :property %> #autopopulate from database
<% f.text_field :property2 %> # I do not want to autopopulate.
<% f.submit 'Submit %>
<% end %>
However, it is best done in the controller:
def edit
# ...
#object.property2.clear
end
Note that if you submit this form with a blank field, it will save a blank string in database, removing whatever was there before.

Rails 4 Select Menu action cannot be nil error

I'm trying to use the Rails form_for and collection select tags to populate a select menu from a database table. When the user hits the submit button there selection will be reflected in my shopping cat table (through the join table CampaignItems). Currently I'm getting a:
First argument in form cannot contain nil or be empty error
The view is in my store index.html.erb file.
Here is my view:
<% form_for #duration do |f| %>
<%= f.collection_select :duration, Duration.all, :id, :name %>
<%= f.submit 'Submit', campaign_items_path(duration_id: duration) %>
<% end %>
My Durations controller:
def index
#durations = Duration.all
end
def new
#duration = Duration.new
end
My Store Controller:
def index
#products = Product.order(:title)
#cart= current_cart
#durations = Duration.all
end
First argument in form cannot contain nil or be empty error
The problem is you have declared #durations = Duration.all in your index action,but you are using #duration in the form.You should be using #durations.
It should be like this
<% form_for #durations do |f| %>
<%= f.collection_select :duration, Duration.all, :id, :name %
<%= f.submit 'Submit', campaign_items_path(duration_id: duration) %>
<% end %>

Create with multiple params issue

I have a controller that looks like this:
def new
#columns = Column.where(:table_id => #table.id)
#row = Row.new(id: #table.id)
end
def create
row_params.each do |row_param|
#row = Row.new(row_param)
#row.column_id = params["column_id"]
if #row.save
redirect_to collection_rows_path, notice: 'item was successfully created.'
else
render action: 'new'
end
end
end
I have a form that looks like:
<%= form_for [#table, #row] do |f| %>
<% #columns.each do |column| %>
<%= column.id %>
<%= hidden_field_tag :column_id, column.id %>
<%= f.label :data %><br>
<%= f.text_field :data %>
<% end %>
<%= f.submit %>
<% end %>
Basically, I'm trying to send multiple params and have them inserted with the column. But I keep getting this error:
undefined methodstringify_keys' for ["data", "No"]:Array` when there is two columns which means there is two text fields and I insert "Hello" in the first one, and "No" in the second.
Two things: Why is it only reading the "No" on the second one instead of both the "Hello" and "No"? And also why am I getting this error?
Thanks for all help!
Answers to your questions:
It is only reading "No" which is your input in the last "Data" text_field since the two text_fields generated in your form_for save their input value in the same params key which is params[:row][:data]. What happens then is the latest value saved to the params[:row][:data] key overrides any previous value it had.
The error undefined method stringify_keys' for ["data", "No"]:Array happens because you create 2 text_fields with the same name which is :data. When you submit the form, an Array is being submitted instead of a String that Rails expects when using text_field.
Solution to your problem:
This seems like an ideal use case for using a nested model form. Basing on your code, it looks like Row belongs_to Table. So in your Table model you'll need to add this code:
#app/models/table.rb
accepts_nested_attributes_for :row
Then add the following code in your RowsController:
#app/controllers/rows_controller.rb
def new
#columns = Column.where(:table_id => #table.id)
#columns.each do |column|
#table.rows.build(column_id: column.id)
end
end
def create
#table = Table.new(table_params)
if #table.save
redirect_to collection_rows_path, notice: 'item was successfully created.'
else
render :new
end
end
private
def table_params
params.require(:table).permit(rows_attributes: [:data, :column_id])
end
Then in your 'rows#new' view:
#app/views/rows/new.html.erb
<%= form_for #table, url: rows_path ,method: :post do |f| %>
<%= f.fields_for :rows do |r| %>
<%= r.object.column.name %>
<%= r.hidden_field :column_id, value: r.object.column_id %>
<%= r.label :data %><br>
<%= r.text_field :data %>
<% end %>
<%= f.submit %>
<% end %>
What the above code will do is allow you to create multiple rows for a column according to the number of columns the table has. This won't work though if a #table has no #columns yet. This assumes that you've created #columns for the #table already. Basing on your code though, it seems like that's already what you're doing.
you want to store 'data' as array in Row
In Rails model Row add
serialize :data, Array
in view
text_field_tag 'row[data][]'
You are getting only 'No' because form for does not know its an array so , it picks the last one And you are getting this error because rails does not know you want to store it as array , it excepts a string but got an array instead.

Resources