rails - NoMethodError in PostsController#create undefined method `post_url' - ruby-on-rails

I'm writing a simple website in which users (authenticated with Devise) can create posts. Upon creating a new post, I'm running into this error in which it won't redirect to the post. Here's my Posts controller:
class PostsController < ApplicationController
before_filter :authenticate_user!
def new
#post = current_user.posts.new
end
def create
#post = current_user.posts.new(post_params)
if #post.save
redirect_to #post
end
end
def show
#post = Post.find_by_id(params[:id])
end
private
def post_params
params.require(:post).permit(:title, :content)
end
end
Here's my routes.rb:
Rails.application.routes.draw do
devise_for :users
resources :users do
resources :posts
end
root 'posts#new'
end
Since the posts resource is nested within users I thought perhaps I should have this in my controller:
if #post.save
redirect_to current_user.#post
end
But that produces a SyntaxError in PostsController#create error.
Can anyone see the problem that's preventing the controller from redirecting to the post after it's created? Any help would be much appreciated.

Try this -
redirect_to [current_user,#post]
OR,
redirect_to user_post_path(current_user, #post)
hope it helps!

In your model, have you allowed for nested attributes? In the controller you want to use build instead of new.

Related

Rails - Listing records of a model in a static page

I am trying to call records of a model (listing all records like Posts.all) to a view that is binded to another controller.
So, I want to reach the index action of Posts_controller which contains the .all listing and .group_by listing that I want to reach and list them in a static page that is listed in Pages_controller (named as yonetim)
This is just for listing the posts for admin view (like the listing in active admin).
I think, I dont need to post any code because the question is quite abstract, but if needed I will edit the question.
* Edit for clarifying*
This is my posts_controller.rb
class PostsController < ApplicationController
before_action :find_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
load_and_authorize_resource
def index
#posts = Post.all.order('postdate DESC')
#posts_by_month = #posts.group_by { |post| post.postdate.strftime('%m - %Y')}
end
def show
end
def new
#post = current_user.posts.build
end
def create
#post = current_user.posts.build(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
def edit
end
def update
if #post.update(post_params)
redirect_to #post
else
render 'edit'
end
end
def destroy
#post.destroy
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:id, :title, :body, :postdate)
end
def find_post
#post = Post.find(params[:id])
end
end
As it can be seen it is a basic blog application. Visitors that reach the root_path (posts#index routed) can see the post records based on grouping of month and year.
What I want to add is reaching the new, edit destroy and index.#posts from a static page that I create for the purpose of admin interface (similar to active Admin gem).
** This is the pages_controller.rb **
class PagesController < ApplicationController
def yonetim
end
end
So when I hit /yonetim (routed to get pages#yonetim), I want the user to see the index action of posts controller with link to new, show, edit and destroy of the record.
***The system also have devise with admin boolean and cancan so if the user not signed in or don't have the authorization for admin usage, they are moved to root_path with an exception.
My problem rises that, I have tried nearly everything to list the #posts records of posts#index method in the pages/yonetim view or in the pages_controller.rb yonetim method.
So that I can list them in my admin view and work around with them.
If anything else is required just let me know.
Thanks in advance,
Mustafa
Multiple options here for pages#yonetim:
Just Redirect to 'posts#index'
Assign view variables (#posts and #posts_by_month) like in posts#index and render template posts/index.
Assign view variables (#posts and #posts_by_month) like in posts#index and render template pages/index (the default view in this case).
The drawback for the first two options is that all links (new/edit/destroy) will link to the PostsController and not to the PagesController, because you are re-using the views that were created for the PostsController.

Rails: Redirecting to post after comment submission

I have a form to submit comments on posts.
After submitting comments, the user should be redirected to the post.
I am getting the following error when I hit the "submit" button:
NameError in CommentsController#create undefined local variable or method `post' for CommentsController...
The error points to the following line in my comments controller:
redirect_to post_path(#post)
Here's my comments_controller.rb:
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
#topic = Topic.find(params[:topic_id])
#post = #topic.posts.find(params[:post_id])
#comment = Comment.new(comment_params)
#comment.post = #post
redirect_to post_path(#post)
end
private
def comment_params
params.require(:comment).permit(:title, :body)
end
end
And here's my route file:
Rclone::Application.routes.draw do
get "comments/create"
devise_for :users
resources :users, only: [:update]
resources :topics do
resources :posts, except: [:index] do
resources :comments, only: [:create]
end
end
get '/posts/:id/comments', to: 'posts#show'
get 'about' => 'welcome#about'
root to: 'welcome#index'
end
What am I doing wrong on the routes file?
Comment.new will not presist or create the post. You need to do #comment.save. Also use pry and pry-nav gem to debug such errors. pry will halt the execution of you program where it finds binding.pry. From that point onwards you can execute your program line by line. Just insert binding.pry one line before where you want to halt execution.
example
def create
binding.pry
#topic = Topic.find(params[:topic_id])
Check you params hash and you will find your bug. My guess is you are going wrong with topic_id or post_id
Links:
http://pryrepl.org/
https://github.com/pry/pry

Why does app go to the create.html.erb view after post submission instead of show.html.erb view? rails 4

Right now in my rails 4 app after the user submits a post I want the app to redirect/render the show view, but right now it just goes to the create view. Here is my Posts controller:
class PostsController < ApplicationController
def show
#post = Post.find(params[:id]) # show
end
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
private
def post_params
params.require(:post).permit(:Title, :Body) #whatsoever your post has
end
#redirect_to post_path(#post)
if #post.save
redirect_to #post.find(params[:id])
else
render :new
end
end
Here are my routes:
Rails.application.routes.draw do
root :to => "pages#index"
devise_for :users
resources :users
resources :pages
resources :posts
end
Thanks for your help.
Looks like there's a few bits of code in wrong places - end statements, and your final if statement at the bottom, which doesn't seem to be in any method.
Something like this should work:
class PostsController < ApplicationController
def show
#post = Post.find(params[:id]) # show
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post.find(params[:id])
else
render :new
end
end
private
def post_params
params.require(:post).permit(:title, :body) #whatsoever your post has
end
end
First, the redirect is wrong. It should be simply:
redirect_to #post
After fixing that, it could be re-rendering because there was an error validating the #post. If #post.save fails the form will be re-rendered, but the URL will stay pointed at the create action.

Relating posts to topics in ruby on rails forum application (high level overview)

Building a forum in ruby for fun and to learn the language. To start this off, i understand basic constructs, but I am very new to server-side languages and am primarily a front-end developer. I am trying to extend my skills.
I don't necessarily want you to code for me (although code examples would be appreciated), but I would like you to explain to me why my code is terrible, which I'm sure it is and tell me how to fix it. Just need some help understand how to relate two models togethers and how to set up that relation in the controllers.
Thanks!
Here are my two models:
Post model:
class Post < ActiveRecord::Base
belongs_to :topic
end
Topic model:
class Topic < ActiveRecord::Base
belongs_to :user
has_many :posts
end
Now here come the controllers. These are where I am really lost. I got the topic creation working, and I tried to just copy what I did in the topic controller. I pretty much knew it wasn't going to work, but I am sorta lost. Here it is...
Topic Controller
class TopicsController < ApplicationController
def index
#topics = Topic.order("sticky desc")
end
def show
#topic = Topic.find(params[:id])
end
def new
#topic = Topic.new
end
def create
#topic = Topic.new(topic_params)
#topic.user = current_user
if #topic.save
redirect_to #topic, notice: "Created topic."
else
render :new
end
end
def edit
#topic = Topic.find(params[:id])
end
def update
#topic = Topic.find(params[:id])
if #topic.update_attributes(topic_params)
redirect_to topics_url, notice: "Updated topic."
else
render :edit
end
end
def destroy
#topic = Topic.find(params[:id])
#topic.destroy
redirect_to topics_url, notice: "Destroyed topic."
end
private
def topic_params
params.require(:topic).permit(:name, :post_content, :sticky)
end
end
Posts Controller
class PostsController < ApplicationController
def index
#posts = Post.order("sticky desc")
end
def show
#post = Post.find(params[:id])
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.user = current_user
if #post.save
redirect_to topics_url, notice: "Post created."
else
render :new
end
end
def edit
#post = Post.find(params[:id])
end
def update
if #post = Post.find(params[:id])
redirect_to topics_url, notice: "Updated post."
else
render :edit
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to topics_url, notics: "Post removed."
end
private
def post_params
params.require(:posts).permit(:content, :created_at, :updated_at)
end
end
I don't believe the views are an issue, and I will post a new question if there is once I get the controller logic figured out.
Again, any help would be appreciated. Please just no comments like, "you should really start back at the beginning", or "you aren't experienced enough, learn this first", because I know I am not experienced, hence why I am here asking you all.
You can show how you would code it, or just explain the logic that needs implemented to me, either is appreciated!
Thanks a ton everyone!
EDIT
I am getting a routing error actually. So obviously the routing is wrong, wasn't sure if it had something to do with the controller code tho: Here is the specific error. (this occurs when I try to click into a topic (I can edit and destroy topics, just not click into them)
Routing Error
No route matches {:action=>"new", :controller=>"posts"}
Try running rake routes for more information on available routes.
Here is my routes files so far:
Forum::Application.routes.draw do
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
resources :sessions
resources :topics do
resources :posts
end
resources :users
root to: 'topics#index'
end
Serve is a little Rack-based web server that makes it simple to serve ERB or HAML from any index. Serve is an optimal apparatus for building HTML models of Rails applications. Serve can likewise deal with SASS, Textile, and Markdown in the event that the suitable diamonds are introduced.
enter image description here

rails Redirect to action incorrect URL

I have a scenario being:
resources :magazines do
resources :articles do
resources :comments
end
end
So as to avoid nesting more than 2 levels deep I have re-factored this to be:
resources :magazines do
resources :articles
end
resources :articles do
resources :comments
end
My article show action URL is:
/magazines/3/articles/11
In this view I have a form for creating a new comment.
When a comment is saved successfully the form redirects which all works well.
When the form submission is not successful I wish to redisplay the view with validations errors displayed. I understand the correct way to do this is to render the 'articles/show' view. This also works and the view is redisplayed with the validation errors shown.
The problem is when the save fails and articles/show is rendered the URL is no longer correct and is shown as:
/articles/11/comments
class ArticlesController < ApplicationController
def show
#article = Article.find(params[:id])
#comments = #article.comments.order(created_at: :asc).page(params[:page]).per_page(5)
#comment = Comment.new
end
end
class CommentsController < ApplicationController
def create
#article = Article.find(params[:id])
#comment = #article.comments.new(discussion_params)
#comment.user_id = current_user.id
if #comment.save
redirect_to #article
else
render 'articles/show'
end
end
private
def discussion_params
params.require(:comment).permit(:content)
end
end
I solved this by changing my routes back to the way it originally was and now the article show action includes the magazine in the url.
I understand this breaks the "no more than 2 levels deep" routing rule but it's the only way I can get it to work.

Resources