Display "micropot feed" from a Rails tutorial in a custom place / view?
I followed Michael Hartl's "Rails Tutorial" and should display the "microflow feed" in the user location (/ members) and not in the root of the site.
I updated the SessionController so that when the user logs in, they are redirected to the new url, but there are two assertions required to submit members that cause errors and prevent the page from loading with the micropost feed.
# app/views/members/index.html.erb
<%= render 'shared/micropost_form' %>
<%= render 'shared/feed' %>
First error:
ArgumentError in MembersController#index
First argument in form cannot contain nil or be empty
return raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
and the second error (seen when removing the first render statement) returnsundefined method 'any?' for nil:NilClass
Part of the problem is that rendering a "microflow feed" in /members
for app/views/members/index.html.erb
seems to need access to app/controllers/microposts_controller.rb
, and I'm not sure how to deal with that.
Update:
micropost_controller.rb
# controllers/micropost_controller.rb
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to '/members'
else
@feed_items = []
render '/members'
end
end
def destroy
@micropost.destroy
flash[:success] = "Micropost deleted"
redirect_to request.referrer || '/members'
end
private
def micropost_params
params.require(:micropost).permit(:content, :picture)
end
def correct_user
@micropost = current_user.microposts.find_by(id: params[:id])
redirect_to '/members' if @micropost.nil?
end
end
_micropost_form.html.erb
# shared/_micropost_form.html.erb
<%= form_for(@micropost, html: { multipart: true }) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost (420 chars max)..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<span class="picture">
<%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
</span>
<% end %>
<script type="text/javascript">
$('#micropost_picture').bind('change', function() {
size_in_megabytes = this.files[0].size/1024/1024;
if (size_in_megabytes > 5) {
alert('Maximum file size is 5MB. Please choose a smaller file.');
}
});
</script>
_feed.html.erb
# shared/_feed.html.erb
<% if @feed_items.any? %>
<ol class="microposts">
<%= render @feed_items %>
</ol>
<%= will_paginate @feed_items %>
<% end %>
MembersController (updated with @Mandeep suggestion below)
class MembersController < ApplicationController
def index
@micropost = current_user.microposts.build
@feed_items = current_user.microposts
end
end
source to share
You don't pass arguments in your parts. You need to do the following:
<%= render 'shared/micropost_form', :locals => { :micropost => @micropost } %>
<%= render 'shared/feed', :locals => { :feed_items => @feed_items } %>
Remember that you need to have these two variables inside your method index
: @micropost
and @feed_items
.
source to share