Path defined in controller and action is getting i

2019-08-06 05:45发布

According to http://guides.rubyonrails.org/layouts_and_rendering.html

I should be able to define the path from a different controller as I have done in my create action in my micropostscontroller:

def create
      @micropost = current_user.microposts.build(params[:micropost])
      if @micropost.save
        flash[:success] = "Micropost created!"
        redirect_to profile_path
      else
        render 'static_pages/profile'
      end
    end

When I unsuccessfully create a post, however (leave it blank or make it too long), the page '/microposts' is rendered, the nonexistent home page of the controller. When I successfully create a micropost I am redirected to the profile path '/profile', and when I've changed render 'static_pages/profile' to redirect_to profile_path the redirect works. Why is the browser ignoring the render request and going to the microposts controller home?

Additionally, the rendered microposts page gives a NoMethodError:

NoMethodError in Microposts#create

undefined method `name' for nil:NilClass

<% provide(:title, @user.name) %>

app/views/static_pages/profile.html.erb:16:in `_app_views_static_pages_profile_html_erb___1610169404003779010_70327969935820'
app/controllers/microposts_controller.rb:10:in `create'

The profile renders fine on its own when when redirected to, as @user is defined in profile action in the static_pages controller. @user = User.find_by_remember_token(cookies[:remember_token])

2条回答
手持菜刀,她持情操
2楼-- · 2019-08-06 06:19

I think you've misunderstood what render does. It just changes which template is rendered. It does not cause any code from the controller related to the template (if there is one) to be executed.

The stack trace shows that it is rendering the file you requested, although it would seem that it expects @user to be defined, which you don't seem to be doing in your create action. Set @user to current_user and you should be fine.

Redirecting is probably a better choice though - if the user refreshes the page it may resubmit the form data, whereas with the redirect that won't happen.

查看更多
欢心
3楼-- · 2019-08-06 06:32

Your create method is attempting to render 'app/views/static_pages/profile.html.erb', but you haven't given it a @user to render. If you revise your code this way it should work:

def create
  @micropost = current_user.microposts.build(params[:micropost])
  if @micropost.save
    flash[:success] = "Micropost created!"
    redirect_to profile_path
  else
    @user = current_user # Add this line!
    render 'static_pages/profile'
  end
end

Note that the path of the microposts#create method is /microposts, so that will still show in your address bar unless you use redirect_to instead of render.

查看更多
登录 后发表回答