简体   繁体   中英

How to change the 'micropost feed' URL from Rails Tutorial?

I'm following Michael Hartl's book 'Rails Tutorial' and need to change the logged in URL to render at /members instead of at the site's root.

I've tried changing home.html.erb from:

<% if logged_in? %>
  <div class="row">
    <aside class="col-md-4">
      <section class="user_info">
        <%= render 'shared/user_info' %>
      </section>
      <section class="stats">
        <%= render 'shared/stats' %>
      </section>
      <section class="micropost_form">
        <%= render 'shared/micropost_form' %>
      </section>
    </aside>
    <div class="col-md-8">
      <h3>Micropost Feed</h3>
      <%= render 'shared/feed' %>
    </div>
  </div>
<% else %>
  <%= render 'covers/non_logged_in_home' %>
<% end %>

to

<% if logged_in? %>
  <%= render 'members/index' %>
<% else %>
  <%= render 'covers/non_logged_in_home' %>
<% end %>

and creating a new partial at views/members/ with he contents extracted from above like this:

  <div class="row">
    <aside class="col-md-4">
      <section class="user_info">
        <%= render 'shared/user_info' %>
      </section>
      <section class="stats">
        <%= render 'shared/stats' %>
      </section>
      <section class="micropost_form">
        <%= render 'shared/micropost_form' %>
      </section>
    </aside>
    <div class="col-md-8">
      <h3>Micropost Feed</h3>
      <%= render 'shared/feed' %>
    </div>
  </div>

after doing this the micropost feed still works as usual, but remains in the site's root. I figure it's a routing issue but am not sure how to handle it as the only routing info in routes.rb for microposts is:

resources :microposts,          only: [:create, :destroy]

Update:

Rails.application.routes.draw do

  get 'members/index' #just added; didn't work.

  get 'covers/new_cover' => 'covers#new_cover', :as => :new_cover

  get 'covers/home'

  get 'covers/new'

  get 'covers/create'

  get 'covers/destroy'

  get 'password_resets/new'

  get 'password_resets/edit'

  get 'account_activations/edit'

  get 'sessions/new' 

  root                'covers#home'
  get    'profile'    => 'static_pages#profile'
  get    'tours'   => 'static_pages#tours'
  get    'blog'   => 'static_pages#blog'
  get    'reviews'   => 'static_pages#reviews'
  get    'contact' => 'static_pages#contact'
  get    'signup'  => 'users#new'
  get    'login'   => 'sessions#new'
  post   'login'   => 'sessions#create'
  delete 'logout'  => 'sessions#destroy'
  resources :users do
    member do
      get :following, :followers
    end
  end
  # resources :users
  resources :account_activations, only: [:edit]
  resources :password_resets,     only: [:new, :create, :edit, :update]
  resources :microposts,          only: [:create, :destroy]
  resources :relationships,       only: [:create, :destroy]

  resources :covers, only: [:home, :index, :new, :create, :destroy]

Update 2:

When updating the route to

get 'members' => 'members#index'

as correctly suggested by @Arslan, the routing succeeds but the following error is returned in its place:

ArgumentError in MembersController#index
First argument in form cannot contain nil or be empty

Further investigation shows this error is caused by one or both of the following render statements contained in app/views/members/index.html.erb :

<%= render 'shared/micropost_form' %>
<%= render 'shared/feed' %>

Contents of these files is:

# _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>

and

# _feed.html.erb
<% if @feed_items.any? %>
  <ol class="microposts">
    <%= render @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>

In you SesssionController class, you can change the redirect method to point to /members :

class SessionsController < ApplicationController

# other code
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      redirect_to '/members'
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end
end

Now, whenever a use successfully logs in your site, he/she will be redirected to /members page.

Edit:

get 'members/index' this will work if you have a class named MembersController , and in that class a method named index . Along with, you should also have a view at app/views/members/index.htmlerb .

And make it explicit like following:

get 'members/index' => 'members#index'

But if you want to invoke any method of any other controller, you can do:

get 'members/index' => 'any_other_controller#any_method' 
# Remember controller name should be in plural: 'members', 'users'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM