Reputation: 808
In my app I'm rendering the partial below in the views/transactions/show.html.erb
, but when I hit submit
I get this error:
undefined local variable or method 'f' for #<PapersController:0x007fa790b51190>
In this line of the controller:
f.html { redirect_to "", notice: "Error: Paper Not created!!"}
:
<%= form_for ( @newPaper ) do |f| %>
<div class="field">
<%= f.label :date, class: 'form-text'%>
<%= f.date_select :date %>
</div>
<br />
<div class="field">
<%= f.label :paper_type %>
<%= f.select(:paper_type, options_for_select(Paper::PAPER_TYPES)) %>
</div>
<br>
<div class="field">
<%= f.label :paper_weight %> :<%= f.number_field :paper_weight, class: 'form-fields' %> -kg.
</div>
<br />
<div class="field">
<%= f.label :env_paper_weight %> :
<%= f.number_field :env_paper_weight, class: 'form-fields' %> -kg.
</div>
<br />
<br>
<div class="actions">
<%= f.submit "Add Paper" %>
</div>
<% end %>
class PapersController < ApplicationController
before_action :set_paper, only: [:edit, :update, :show, :destroy]
before_action :paper_owner, only: [ :edit, :update, :destroy]
def index
all_paper_type_values = Paper.all.pluck(:paper_type).uniq
@data_for_chart = all_paper_type_values.map do |paper_type|
{ name: paper_type, data: Paper.where(paper_type: paper_type).group_by_month(:created_at).sum(:paper_weight)}
end
@pappi = Paper.all
@newPaper = Paper.new
end
def new
@paper = Paper.new
end
def create
@paper = Paper.new(paper_params)
@paper.user_id = current_user.id
if (@newPaper.save)
redirect_to transaction_path(current_user), :notice => "Post has been saved successfully."
else
f.html { redirect_to "", notice: "Error: Paper Not created!!"}
end
end
def update
if @paper.update(paper_params)
flash[:success] = "Line was successfully updated"
redirect_to papers_path(@paper)
else
render 'edit'
end
end
def destroy
@paper.destroy
flash[:danger] = "Line was successfully destroyed"
redirect_to transaction_path(current_user)
end
private
def set_paper
@paper = Paper.find(params[:id])
end
def paper_params
params.require(:paper).permit(:user_id, :paper_type, :date, :paper_weight, :env_paper_weight)
end
def paper_owner
unless @paper.user_id == current_user.id
flash[:notice] = 'Access denied as you are not owner of this Job'
redirect_to papers_path
end
end
end
class TransactionsController < ApplicationController
def new
@paper = current_user.papers.build
@kwst = current_user.kwsts.build
@hwater = current_user.hwaters.build
@transport = current_user.transports.build
end
def show
@user = User.find(params[:id])
@username = params[:id]
@newPaper = Paper.new
@newKwst = Kwst.new
@newHwater = Hwater.new
@newTransport = Transport.new
@papers = current_user.papers.order(created_at: :desc).limit(5)
@kwsts = current_user.kwsts.order(created_at: :desc)
@hwaters = current_user.hwaters.order(created_at: :desc)
@transports = current_user.transports.order(created_at: :desc)
end
end
I've changed the:
<%= form_for ( @newPaper ) do |f| %>
to
<%= form_for Paper.new do |f| %>
In the paper_controller.rb
but still get the error. I'm kind of lost here, can someone help me?
Upvotes: 0
Views: 2718
Reputation: 33542
undefined local variable or method 'f' for <PapersController:0x007fa790b51190>
The error triggers in this line
f.html { redirect_to "", notice: "Error: Paper Not created!!"}
as you not defined f
in the controller method.
It seems you are trying write your create
method using respond_to
, then the create method should look like below
def create
@paper = Paper.new(paper_params)
@paper.user_id = current_user.id
respond_to do |f|
if (@paper.save) #not @newPaper
f.html {redirect_to transaction_path(current_user), :notice => "Post has been saved successfully."}
else
f.html { redirect_to "", notice: "Error: Paper Not created!!"}
end
end
end
Upvotes: 1
Reputation: 30135
The f
in the two contexts you show is completely unrelated. Views and controllers share attributes (for a given request) but not local variables, and further your f
variable is limited to the form_for
block (from the do
to the matching end
), it has nothing at all to do with the PapersController#create
method.
f.html
could be a respond_to, but thats not really needed if you are only supporting HTML.
It is not really clear what you intend f.html { redirect_to "", notice: "Error: Paper Not created!!"}
since that is in a different controller entirely. If you just want to redirect somewhere, then just use redirect_to
directly, drop the f.html
thing.
e.g.
redirect_to transaction_path(current_user), notice: "Error: Paper Not created!!"
If you want to display errors and keep the original form values then normally, you would have the form (normally an action called new
) and the create
in the same controller, and reuse the view.
class PapersController
def new
@paper = Paper.new
render
end
def create
@paper = Paper.new(paper_params)
@paper.user = current_user
if @paper.save
redirect_to transaction_path(current_user), notice: "Post has been saved successfully."
else
render "new" # form_for will keep values from @paper, can also display @paper.errors
end
end
end
Allthough it is of course possible to render the same form/view from multiple controllers with full errors, etc. if you wish.
Upvotes: 0