Domanda

Currently I have an edit form as follows:

<li>
    <%= form_for @ingredient do |f| %>
        <span class="span2"><%= f.text_field :name, placeholder: "#{@ingredient.name}" %></span>
        <span class="span1"><%= f.text_field :quantity, placeholder: "#{@ingredient.quantity}" %></span>
        <span class="span1"><%= f.text_field :unit, placeholder: "#{@ingredient.unit}" %></span>
        <span class="span3">Added: <%= @ingredient.updated_at.strftime("%d %b. at %H:%M") %></span>
        <span class="span2"><%= f.text_field :expiration, placeholder: "#{@ingredient.expiration}" %></span>
        <span class="span2"><%= f.submit "Submit", class: "btn btn-small" %></span>
    <% end %>
</li>

When I click submit my log file shows the follow:

Started PATCH "/pantries/112" for 127.0.0.1 at 2014-04-29 18:03:35 -0400
Processing by PantriesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"NUSmadjWCVVLHOZmncKD5D48L+7ZMa3DEbZ9Y+Y+Pnc=", "pantry"=>{"name"=>"test1", "quantity"=>"1", "unit"=>"cup", "expiration"=>"2015-05-05"}, "commit"=>"Submit", "id"=>"112"}
  [1m[35mUser Load (0.5ms)[0m  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '27ecdc04fc67375fd3567c89fbe831e4d4919d09' LIMIT 1
  [1m[36mPantry Load (0.3ms)[0m  [1mSELECT "pantries".* FROM "pantries" WHERE "pantries"."id" = $1 LIMIT 1[0m  [["id", "112"]]
  [1m[35m (0.2ms)[0m  BEGIN
  [1m[36m (0.1ms)[0m  [1mCOMMIT[0m
Redirected to http://localhost:3000/users/1/pantry
Completed 302 Found in 6ms (ActiveRecord: 1.1ms)

It doesn't raise an error it just does not update at all, but says that the update completed successfully.

pantry.rb

class Pantry < ActiveRecord::Base
    before_save { self.name = name.downcase }
    belongs_to :user

    validates :name, presence: true
    validates :user_id, presence: true
end

pantries_controller

def update
        @ingredient = Pantry.find(params[:id])
        if @ingredient.update_attributes(params[ingredient_params])
            redirect_to pantry_user_path(current_user), :flash => {info: "Ingredient Updated"}
        else
            redirect_to pantry_user_path(current_user), :flash => {info: "Failed"}
        end
end
private
        def ingredient_params
            params.require(:pantry).permit(:name, :quantity, :unit, :expiration, :created_at, :updated_at)
        end

schema:

create_table "pantries", force: true do |t|
    t.string   "name"
    t.string   "quantity"
    t.string   "unit"
    t.integer  "user_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.date     "expiration"
  end

  add_index "pantries", ["expiration"], name: "index_pantries_on_expiration", using: :btree
  add_index "pantries", ["quantity"], name: "index_pantries_on_quantity", using: :btree
  add_index "pantries", ["unit"], name: "index_pantries_on_unit", using: :btree

If I replace @ingredients.update_attributes with @ingredient.update_column(:expiration, params[:pantry][:expiration]) the update takes place on that column. Falling back to update_column is not ideal. I understand update_attributes and update_attributes! call callbacks while update_column does not. I don't see any issue with the callbacks and no error messages are given. Anyone have an idea on what the issue might be?

È stato utile?

Soluzione

Change your update action as below:

def update
        @ingredient = Pantry.find(params[:id])
        if @ingredient.update_attributes(ingredient_params) ## Call ingredient_params
            redirect_to pantry_user_path(current_user), :flash => {info: "Ingredient Updated"}
        else
            redirect_to pantry_user_path(current_user), :flash => {info: "Failed"}
        end
end

With Rails 4 strong parameters concept, you need to whitelist the attributes that you would like to be saved in database.

Currently, you are using params[ingredient_params] instead of calling ingredient_params which is causing this issue

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top