问题
Firstly, I would like to describe what I am going to do. So, my application is set of tasks (eg. exercises depend on writing computer program) which user it available to send solutions through form and server will have compiled it and return results of process.
My problem is that I have model Solution which is presented below:
Solution(id: integer, exercise_id: integer, code: string, user_id: integer,
created_at: datetime, updated_at: datetime, language_id: integer)
and exercise_id, user_id, language_id are foreign keys and postgresql return error that it couldn't be null values...
The form which I use to send this information looks like below:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [@user, @exercise, @solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
Frankly speaking I don't how to include more information such as user.id or exercise.id. Params look like:
@_params
{"utf8"=>"✓", "authenticity_token"=>"abwhTn3KrVneli0pCVccoWHyzlI7cRTFK5Wo7DdYRK+lL4GwZ8jUPqdzn8ZznCHsWTkfDAFS2RP6gTkWuk33iw==", "solution"=>{"code"=>"ds", "language_id"=>"C++"}, "commit"=>"Wyślij", "controller"=>"solutions", "action"=>"create", "exercise_id"=>"1"}
SolutionController
class SolutionsController < ApplicationController
def index
@solutions = Solution.last(20)
end
def new
@solution = Solution.new
end
def create
@solution = Solution.new(solution_params)
if @solution.save
redirect_to @solution
else
render :new
end
end
def edit
@solution = Solution.find(params[:id])
if @solution.update(solution_params)
redirect_to @solution
else
render :edit
end
end
def destroy
end
private
def solution_params
params.require(:solution).permit(:language_id, :code)
end
end
Edit:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [@user, @exercise, @solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.hidden_field :exercise_id, value: @exercise.id %>
<%= f.hidden_field :user_id, value: @user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
回答1:
You could 1) add hidden_fields in your form to set the missing attributes:
<div class="form-group">
<%= f.hidden_field :exercise_id, value: @exercise.id %>
<%= f.hidden_field :user_id, value: @user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
Make sure to add these attributes to the solution_params permitted parameters:
def solution_params
params.require(:solution).permit(:language_id, :code, :exercise_id, :user_id)
end
A better idea would be to manually set the exercise and user in the controller and leave your solution_params as is. That way you're not allowing the exercise and user to be set by mass assignment, which could be spoofed.
So instead do 2) in your controller:
def create
@solution = Solution.new(solution_params)
@solution.exercise_id = params[:exercise_id]
@solution.user_id = params[:user_id]
if @solution.save
redirect_to @solution
else
render :new
end
end
I'm assuming that :exercise_id and :user_id are in the URL. If not add them as hidden_fields as needed (but this time not on the form object):
<%= hidden_field_tag :user_id, @user.id %>
Also remember to actually select a language_id from the dropdown before you submit the form.
来源:https://stackoverflow.com/questions/27551355/rails-how-to-send-some-information-from-one-form-to-other-controller