简体   繁体   中英

Rails - create and update action don't work

I'm a beginner in Rails, I have a Suplement controller and I can't create or edit a suplement (delete works fine). I'm not getting any errors, just nothing happens when I click and everything's working fine from the console. I tried everything I know (which is not much) and I couldn't find a question like this, similar answers didn't help. I'd appreciate any help, thanks!

class SuplementsController < ApplicationController
  before_action :set_suplement, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!
  def index
   @suplement = Suplement.all.order("created_at DESC")
  end

  def new
    @suplement = Suplement.new
  end

  def create
    @suplement = Suplement.new(suplement_params)
  if @suplement.save
    redirect_to '/suplements'
  else
    render '/suplements/new'
  end
end

def show
end

def edit
end

def update
  if @suplement.update(suplement_params)
    redirect_to '/suplements'
  else
    redirect_to '/suplements/new'
  end
end

def destroy
  @suplement.destroy
    redirect_to '/suplements'
end

private

  def set_suplement
    @suplement = Suplement.find(params[:id])
  end

  def suplement_params
    params.require(:suplement).permit(:name,
                                      :number_of_units,
                                      :daily_dosage_in_units,
                                      :number_of_days,
                                      :suplement_cost
                                      )
  end
end

Here's a view:

<h1>Create new suplement</h1>

  <%= form_for(@suplement) do |f| %>

  <%= render 'form', suplement: @suplement %>

  <div class="actions">
    <%= f.submit %>
  </div>

<% end %>

and here's a form partial:

<%= form_for(@suplement) do |f| %>
    <% if @suplement.errors.any? %>
      <div id="error_explanation">
        <h2><%= pluralize(@suplement.errors.count, "error") %> prohibited this suplement from being saved:</h2>

        <ul>
        <% @suplement.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
        </ul>
      </div>
    <% end %>

    <div class="field">
      <%= f.label :name %>
      <%= f.text_field :name %>
    </div>

    <div class="field">
      <%= f.label :number_of_units %>
      <%= f.text_field :number_of_units %>
    </div>

    <div class="field">
      <%= f.label :daily_dosage_in_units %>
      <%= f.text_area :daily_dosage_in_units %>
    </div>

    <div class="field">
      <%= f.label :number_of_days %>
      <%= f.text_area :number_of_days %>
    </div>

    <div class="field">
      <%= f.label :suplement_cost %>
      <%= f.text_area :suplement_cost %>
    </div>

  <% end %>

Also my models:

class Suplement < ApplicationRecord
  belongs_to :user
  validates :name,
            :number_of_units,
            :daily_dosage_in_units,
            :number_of_days,
            :suplement_cost,
            presence: true
end

and

 class User < ApplicationRecord

   devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

   has_many :suplements
 end

It looks like the problem is that you have 2 forms. Uou have a form_for @suplement in your _form.html.erb file and also in your new.html.erb file. Try removing it from new.html.erb so your file looks like this

new.html.erb

<h1>Create new suplement</h1>
<%= render 'form', suplement: @suplement %>

_form.html.erb

<%= form_for(@suplement) do |f| %>
    <% if @suplement.errors.any? %>
      <div id="error_explanation">
        <h2><%= pluralize(@suplement.errors.count, "error") %> prohibited this suplement from being saved:</h2>

        <ul>
        <% @suplement.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
        </ul>
      </div>
    <% end %>

    <div class="field">
      <%= f.label :name %>
      <%= f.text_field :name %>
    </div>

    <div class="field">
      <%= f.label :number_of_units %>
      <%= f.text_field :number_of_units %>
    </div>

    <div class="field">
      <%= f.label :daily_dosage_in_units %>
      <%= f.text_area :daily_dosage_in_units %>
    </div>

    <div class="field">
      <%= f.label :number_of_days %>
      <%= f.text_area :number_of_days %>
    </div>

    <div class="field">
      <%= f.label :suplement_cost %>
      <%= f.text_area :suplement_cost %>
    </div>
    <div class="actions">
      <%= f.submit %>
    </div>
  <% end %>

What I did is:

1) Deleted form_for and submit button inside new.html.erb 2) Added submit button in _form.html.erb, so the variable f is accessible

Also, since you are passing a variable @suplement to partial local variable suplement , you can use the variable suplement inside _form.html.erb file without the @ sign

EDIT (Regarding comment):

Your getting User presence validation Error, because from Rails 5.0, belongs_to associations are automatically validated for presence.

If you do not need a user in your suplement object all the time then you should change your association to belongs_to :user, optional: true

OR

if you do need the user, and you always want it to be the current user logged in, then add this to your _form

<%=f.hidden_field :user_id, current_user.id %>

This will use Devise helper method to get the current logged in user and assign it to this hidden field. Don't forget to add this parameter in your controler suplement_params controller method

In the #edit of your controller, you need to set the value of the @suplement variable.

def edit
  @suplement = Suplement.find(params[:id])
end

you should also include the above line as the first line in your #update method

def update
  @suplement = Suplement.find(params[:id])
  if @suplement.update_attributes(suplement_params)
    # continued...
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM