user5639219
user5639219

Reputation:

Missing partial in rails

Hello i want to show @detail in /notes/show_html.slim, but i have error Missing partial details/_detail with how i can output @detail in /notes/show.html.slim

routes.rb

Rails.application.routes.draw do
  root 'static_pages#home'
  match '/about_me', to: 'static_pages#about', via: 'get'
  devise_for :users
  resources :users, only: [:index, :show]
  resources :notes do
    resources :details
  end
end

details_controller.rb

class DetailsController < ApplicationController
  def new
    @note = Note.find(params[:note_id])
    @detail = Detail.new
  end

  def create
    @note = Note.find(params[:note_id])
    @detail = @note.details.build(detail_param)
    if @detail.save
    redirect_to note_path(@note)
  end
end

  def destroy
    @note = Note.find(params[:note_id])
    @detail = @note.details.find(params[:id])
    @detail.destroy
    redirect_to note_path(@note)
  end

  private

  def detail_param
    params.require(:detail).permit(:body)
  end
end

and views

/notes/show.html.slim

#note
  #post_content
   .show
     h1 = @note.title
     = render @note.details #or = render 'details/show'?
   .date
    p Created #{time_ago_in_words(@note.created_at)} ago
    hr
   -if @note.user_id == current_user.id
    p=link_to 'Edit', edit_note_path(@note), class: 'btn btn-primary'
    p=link_to 'delete', note_path, method: :delete, data: { confirm: "Delete note?" },  class: 'btn btn-primary'
    p=link_to  'Add details', new_note_detail_path(@note), class: 'btn btn-primary'
    hr
   .body
      p #{@note.body}

/details/show.html.slim

div class="details"
  p #{@detail.body}

Upvotes: 0

Views: 1907

Answers (5)

Van Huy
Van Huy

Reputation: 1627

From Rails doc:

Partials are named with a leading underscore to distinguish them from regular views

So you need to change details/show.html.slim to details/_show.html.slim.

After that, you can use partials in your notes/show.html.slim like

= render partial: "details/show", collection: @note.details, as: :detail

Note that to render a collection, using :collection option is shorter than an each loop.

And details/_show.html.slim is like

# details/_show.html.slim
div.details
  p= detail.body

Upvotes: 0

aledustet
aledustet

Reputation: 1001

The partial syntax for rails is _name_of_partial.html.erb/slim/haml Thats the error you are getting. My advice to you is to stick with the conventions, if you wish to render the details data once again, in another view you should have a partial _data.html.slim inside your details views folder, so you can call it from the show on detail and from the show on your notes show, it could be like this

notes/show.html.slim

#note
#post_content
 .show
   h1 = @note.title
   = render 'details/data' data: @details
   .date
   p Created #{time_ago_in_words(@note.created_at)} ago
   hr
   -if @note.user_id == current_user.id
   p=link_to 'Edit', edit_note_path(@note), class: 'btn btn-primary'
   p=link_to 'delete', note_path, method: :delete, data: { confirm: "Delete note?" },  class: 'btn btn-primary'
   p=link_to  'Add details', new_note_detail_path(@note), class: 'btn btn-primary'
   hr
   .body
     p #{@note.body}

details/_data.html.slim

div class="details"
  p #{data.body}

I also suggest you to read throughly http://guides.rubyonrails.org/layouts_and_rendering.html

Upvotes: 0

Sergey Sokolov
Sergey Sokolov

Reputation: 994

Partial name in Rails should start with _ (_partial.html.slim) and next you can

<%= render :partial => 'tasks/your_partial' %>

More info you can find here

Upvotes: 0

eugen
eugen

Reputation: 9226

That is consistent with how collection rendering works in Rails. @note.details is a collection of objects, so when you do a render @note.details Rails will loop over the collection, and for each object in the collection determines which partial to use by calling to_partial_path on that object. In this case, the method will return details/detail so that's what Rails will try to render. If you want to specify a different partial, you need to change the rendering to something like:

= render partial: 'OTHER_PARTIAL', collection: @note.details

Upvotes: 0

Magnuss
Magnuss

Reputation: 2310

= render @note.details, expects to render each object (detail) using a template called details/_detail.html.slim

You can read about it here

details/show.html.slim is meant to render the show action for the specific resource.

details/_detail.html.slim is meant to e.g. render each row for a details/index.html.slim passing the detail object.

If your show template really fits, then you can do something like this:

# /notes/show.html.slim
= render @note.details.each do |detail|
  = render 'details/show', detail: detail

--

# /details/show.html.slim
- detail ||= @detail
div class="details"
  p #{detail.body}

Upvotes: 3

Related Questions