问题
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_field
s 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