Reputation: 3553
I was hoping someone can give me some insights on how nested resources and more specifically how to tie it with CarrierWave.
I'm getting an error undefined method 'photos_path'
and am a bit stuck on how do go about getting this to work.
I want to be able to have the following urls
site.com/animal/dog/photos/new
site.com/animal/dog/photos/my-dog-in-the-park
Should I be using a nested form? any help is much appreciated.
My Routes
root to: "home#index"
resources :animal do
resources :photos
end
My home view
<%= link_to "Add Dog Photo", new_animal_photo_path(animal_permalink: "dog") %>
My _form partial
<%= form_for [@animal, @photo], :html => {:multipart => true} do |f| %>
<%= f.hidden_field :animal_permalink %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.file_field :image %>
</p>
<p>
</p>
<p><%= f.submit %></p>
<% end %>
My Photo model
class Photo < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
before_create :set_permalink
before_update :set_permalink
belongs_to :dog
mount_uploader :image, PhotoUploader
def set_permalink
self.permalink = title.parameterize
end
def to_param
permalink.parameterize
end
end
My Animal model
class Animal < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
has_many :photos
scope :dog, where(name: "Dog")
def to_param
permalink.parameterize
end
end
My PhotoController
class PhotosController < ApplicationController
def show
@photo = Photo.find(params[:id])
end
def new
@animal = Animal.find_by_permalink(params[:id])
@photo = Photo.new
end
def create
@photo = Photo.new(photo_params)
if @photo.save
flash[:notice] = "Successfully created photo."
redirect_to root_url
else
render :action => 'new'
end
end
def edit
@photo = Photo.find(params[:id])
end
def update
@photo = Photo.find(params[:id])
if @photo.update_attributes(photo_params)
flash[:notice] = "Successfully updated photo."
redirect_to root_url
else
render :action => 'edit'
end
end
def destroy
@photo = Photo.find(params[:id])
@photo.destroy
flash[:notice] = "Successfully destroyed photo."
redirect_to root_url
end
private
def photo_params
params.require(:photo).permit(:title, :image, :animal_id)
end
end
Thanks for taking a look. Any help is much appreciated.
Upvotes: 0
Views: 566
Reputation: 3909
I've made a few adjustments to your code.
Notice I've added an "s" to animal
root to: "home#index"
resources :animals do
resources :photos
end
notice I've removed an "s" from animals. I've changed animal_permalink to id because that is the default that would be expected by a nested resource. Also, note that, in your photos controller new method you check for the "id" param, not the animal_permalink param.
new_animal_photo_path(id: "dog")
In your _form. set the value of the animal_permalink
<%= f.hidden_field :animal_permalink, value: @animal.permalink %>
This assumes that Photo will be able to recognize the animal_permalink attribute and that you've defined an animal.permalink method/attribute. I'm not familiar with the permalink approach, so you may have to fiddle around a bit, but this should steer you in the right direction (I would normally set the :dog_id/:animal_id attribute).
Let me know how that goes.
Upvotes: 1