новичок здесь застрял на вложенных ресурсах. У меня есть модель image.rb
, которая хранит изображения на облачном CDN. Получив все, что работает, я решил, что мне нужно классифицировать изображения, поэтому я создал модель category.rb
которая просто имеет имя, на данный момент.
Я медленно работал с ошибками после добавления модели category
и контроллера/представлений, и все было хорошо, пока это не было. Я в тупик. Уже несколько часов мы отправляемся в поиски и решили, что я на стене... так что, естественно, я прихожу сюда, надеясь, что кто-то сможет просветить меня. Заранее спасибо! <3 SO
Вот ошибка (она в настоящее время бросает ее на ссылку "edit"
, но я думаю, что она будет ее бросать на "delete"
а также после того, как я получу редактирование, поэтому я тоже менял их):
No route matches {:category_id=>nil, :id=>#<Image id: 16, title: "mario", description: "i belong to category 2!", upload_date: nil, created_at: "2014-03-15 01:13:54", updated_at: "2014-03-15 01:13:54", category_id: 2>} missing required keys: [:category_id]
<td><%= link_to "Show", [@category, image] %></td>
<% if admin? %>
<td><%= link_to "Edit", edit_category_image_path(@category, image) %></td>
<td><%= link_to "Delete", [@category, image], confirm: "Are you sure you want to delete \"#{image.title}\"?", method: :delete %></td>
<% end %>
</tr>
Вот моя модель Image
:
class Image < ActiveRecord::Base
has_attachment :image_file, accept: [:jpg, :png, :gif]
validates :title, presence: true
belongs_to :category
end
Вот модель Category
:
class Category < ActiveRecord::Base
has_many :images
end
Вот контроллеры для каждого:
class ImagesController < ApplicationController
before_filter :authenticate_admin, except: [:index, :show]
def index
@images = Image.all
end
def show
@image = Image.find(params[:category_id])
end
def new
@category = Category.find(params[:category_id])
@image = @category.images.build(image_params)
end
def create
@category = Category.find(params[:category_id])
@image = @category.images.build(image_params)
if @image.save
render "show"
else
render "new"
end
end
def destroy
@image = Image.find(params[:id])
@image.destroy
redirect_to images_path
end
def edit
@category = Category.find(params[:category_id])
@image = @category.images.find(params[:id])
end
def update
@category = Category.find(params[:category_id])
@image = @category.images.find(params[:id])
if @image.update(image_params)
render "show"
else
render "edit"
end
end
private
def image_params
params.require(:image).permit(:title, :description, :image_file, :category_id)
end
end
и контроллер Category
class CategoriesController < ApplicationController
def index
@categories = Category.all
end
def show
redirect_to category_images_path(params[:id])
end
def new
@category = Category.new
end
def create
@category = Category.new(category_params)
if @category.save
redirect_to @category
else
render "new"
end
end
def destroy
@category = Category.find(params[:id])
@category.destroy
redirect_to categories_path
end
def edit
@category = Category.find(params[:id])
end
def update
@category = Category.find(params[:id])
if @category.update(category_params)
redirect_to @category
else
render "edit"
end
end
private
def category_params
params.require(:category).permit(:title)
end
end
Вот файл маршрутов:
Portfolio::Application.routes.draw do
devise_for :users
resources :blogs
resources :categories do
resources :images
end
root "index#index"
#attachinary
mount Attachinary::Engine => "/attachinary"
end
От googling вокруг я продолжал сталкиваться с людьми, у которых проблемы с ним связаны с form partials
поэтому вот _form.html.erb
Я использую для Image
всякий случай, если это необходимо:
<%= form_for([@category, @image]) do |f| %>
<%= render "error" %>
<p>
<%= f.label :title %>
<br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.label "Upload image" %><br>
<%= f.attachinary_file_field :image_file %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
ImagesController
class ImagesController < ApplicationController
before_action :load_category
before_action :set_image, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_admin, except: [:index, :show]
def index
@images = @category.images.all
end
def show
end
def new
@image = @category.images.new
end
def create
@image = @category.images.new(image_params)
if @image.save
render "show"
else
render "new"
end
end
def destroy
@image.destroy
redirect_to images_path
end
def edit
end
def update
if @image.update(image_params)
render "show"
else
render "edit"
end
end
private
def load_category
@category = Category.find(params[:category_id])
end
def set_image
@image = @category.images.find(params[:id])
end
def image_params
params.require(:image).permit(:title, :description, :image_file, :category_id)
end
end
Попробуйте использовать before_action
вызов before_action
для установки необходимых переменных экземпляра. Здесь я загрузил категорию и изображения с помощью частного метода. Это экономит много времени. Вы даже можете увидеть это, когда создаете строительные леса.
before_filter
был псевдонимом как before_action
чтобы упростить его функцию.
Корневой путь обычно определяется во второй строке маршрутов, поэтому его ясность.
Ваши названные пути не похожи на проблему. Это в основном ваш контроллер изображений
Я предлагаю вам создать новое приложение rails, используя строительные леса, чтобы посмотреть на него контроллеры.
rails g scaffolding images