Create a post as a user and assign it to a group - ruby-on-rails

In my rails application I have made three models, User, Group and Post.
I am trying to make it so that #post.group is equal to #group.id
The post is posted from a render inside of the group#show controller and then redirects itself to the post#create controller. How do I set the #post.group to #group.id?
GroupsController
class GroupsController < ApplicationController
before_action :set_group, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#groups = Group.all
respond_with(#groups)
end
def show
#group_id = #group.id
respond_with(#group)
end
def new
#group = Group.new
respond_with(#group)
end
def edit
end
def create
#group = Group.new(group_params)
#group.save
respond_with(#group)
end
def update
#group.update(group_params)
respond_with(#group)
end
def destroy
#group.destroy
respond_with(#group)
end
private
def set_group
#group = Group.find(params[:id])
end
def group_params
params.require(:group).permit(:name, :description, :motto, :usercount, :group, :id, :groupid)
end
end
PostsController
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#posts = Post.all
respond_with(#posts)
end
def show
respond_with(#post)
end
def new
#post = Post.new
respond_with(#post)
end
def edit
end
def create
#post.group = #group_id
#post = Post.new(post_params)
#post.save
respond_with(#post)
end
def update
#post.update(post_params)
respond_with(#post)
end
def destroy
#post.destroy
respond_with(#post)
end
private
def set_post
#post = Post.find(params[:id])
end
def set_group
#group = Group.find(params[:id])
end
def post_params
params.require(:post).permit(:body, :group, :id)
end
def group_params
params.require(:group).permit(:id, :groupid, :group)
end
end
PostModel
class Post < ActiveRecord::Base
belongs_to :group
end
GroupsModel
class Group < ActiveRecord::Base
has_many :posts
end
The current code that I have returns the error undefined methodgroup=' for nil:NilClass`
Any help is appreciated!

You should start from creating Post instance, because you don't do this. I would do it like this:
def create
#post = #group.posts.build(post_params)
if #post.save
# handle success
else
# handle error
end
end
What's more, you should set before_action :set_group in your PostsController.

Related

Friendly_id not showing up on rails

Hi guys im creating blog with friendly id, but its not working..
The problem is when i tried to edit the title, friendly id came up, but when i reopen, it just show the blog id. not the slug anymore
this is the code
in my model :
class Blog < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :slugged
def should_generate_new_friendly_id?
slug.blank? || title_changed?
end
end
my blog controller
class BlogsController < ApplicationController
before_action :set_blog, only: [:show, :edit, :update, :destroy]
def index
#blogs = Blog.all
end
def show
#blog = Blog.friendly.find(params[:id])
end
def new
#blog = Blog.new
end
def create
#blog = Blog.new(blog_params)
if #blog.save
redirect_to blog_path(#blog), notice: "Successfully Created"
else
render :new
end
end
def edit
end
def update
if #blog.update(blog_params)
redirect_to blog_path(#blog), notice: "Successfully Update"
else
render 'edit'
end
end
def destroy
#blog.destroy
redirect_to blog_path(#blog)
end
private
def set_blog
#blog = Blog.friendly.find(params[:id])
end
def blog_params
params.require(:blog).permit(:title, :body, :image, :category_id)
end
end
i spent so much time to solve this.. please help

ruby- Couldn't find Project with 'id'=

I got this Nested Resources Error like below:
ActiveRecord::RecordNotFound at /admin/projects/2/project_comments
Couldn't find Project with 'id'=
routes.rb
namespace :admin do
resources :users
resources :projects do
resources :project_users
resources :project_comments
end
end
project.rb
has_many :project_comments
project_comment.rn
belongs_to :project
project_comments_co
class Admin::ProjectCommentsController < ApplicationController
before_action :set_project_comment, only: [:show, :edit, :update, :destroy]
before_action :set_project
def your_action
# these are for debugging
puts params.inspect
puts params[:option_id]
#event = Event.find(params[:event_id])
#option = Option.find(params[:option_id])
end
def index
#project_comments = #project.project_comments.all
end
def new
#project_comment = #project.project_comments.new
end
def create
#project_comment = #project.project_comments.new(project_comment_params)
if #project_comment.save
else
end
end
def show
end
def edit
end
def update
if #project_comment.update(project_comment_params)
else
end
end
def destroy
#project_comment.destroy
end
private
def set_project
#project = Project.find(params[:id])
end
def set_project_comment
#set_project_comment = ProjectComment.find(params[:id])
end
def project_comment_params
params.require(:project_comment).permit(:project_id, :user_id, :comment)
end
end
Thank you for helping me!
As you are inside the ProjectCommentsController the params[:id] will give you the id of ProjectComment and not of Project. So in your method:
def set_project
#project = Project.find(params[:id])
end
Change the params[:id] to params[:project_id] which will solve your issue.
This error say that Rails is not able to find any Project record with this id.
Is there any Project record in a database?
Please post stack trace.
change your set_project function with below code:
private
def set_project
#project = Project.find(params[:project_id])
end

Create a has_many :posts for categories in rails

I want to the category I create in relation with the post I want to create. I don't want to add a gem or anything else I think we can do it with has_manyand belongs_to
I create two tables Posts and Category and I want to choose a category in a collection and this is written in the post new#view I want to create and on the post show#view and post index#view.
Models for posts is :
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
TAGS = ["Design", "Mode", "Tendance", "Life-Style", "Tradition", "Gastronomie", "Insolite", "Technologie"]
validates :tag, inclusion: { in: Post::TAGS, allow_nil: false }
mount_uploader :cover, ImageUploader
end
and categories is foreign keys for posts here is the model
class Category < ActiveRecord::Base
has_many :posts
NAMES = ["JAPON", "CHINE", "INDE"]
validates :name, inclusion: { in: Category::NAMES, allow_nil: false }
end
Posts Controllers are here
class PostsController < ApplicationController
before_filter :authenticate_user!, except: [:index, :show]
before_action :find_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all
end
def show
# #alert_message = "Vous lisez #{#post.title}"
end
def new
# if current_user and current_user.admin?
#post = Post.new
# else
# redirect_to posts_path
# end
end
def create
# if current_user and current_user.admin?
#post = current_user.posts.new(post_params)
##post = current_user.posts.new(post_params)
if #post.save
redirect_to #post
else
render :new
end
# else
# render 'shared/404.html.erb'
# 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 :back
end
private
def find_post
#post = Post.find(params[:id])
end
# def set_category
# #post_category = Category.find(params[:category_id])
# end
def post_params
params.require(:post).permit(:title, :subtitle, :introduction, :body, :cover, :tag, :category_id)
end
end
and categories_controller are here
class CategoriesController < ApplicationController
before_action :set_category, only: [:show, :new, :create, :destroy]
def show
#category = Category.find(params[:id])
end
def index
#categories = Category.all
end
def create
#category = Category.new(category_params)
if #category.save
redirect_to #post
else
render :new
end
end
def new
#category = Category.new
end
def edit
end
def update
end
def destroy
#category = Category.find(params[:id])
#category.destroy
redirect_to post_path(#post)
end
private
# def set_post
# #post = Post.find(params[:post_id])
# end
# def set_category
# #category = Category.find(params[:category_id])
# end
def set_category
if params[:id].present?
#category = Category.find(params[:id])
else
#category = Category.new
end
end
# def find_category
# #category = Category.find(params[:id])
# end
def category_params
params.require(:category).permit(:name, :description)
end
end
Please could you show the right way to add a category I choose in collection and I show in post new#view show#view index#view.
Thank you for your help.
If a category can belong to more than one post, I would recommend using a has_may_through relationship for your data model.
class Post
has_many :post_categories
has_many :categories, through: post_categories
accepts_nested_attributes_for :categories
end
class Category
has_many :post_categories
has_many :posts, through: post_categories
end
class PostCategory
belongs_to :posts
belongs_to :categories
end
You will need to create a migration to add the 'through' table, PostCategory, which will consist of a post_id and a category_id.
In the controller
def new
#post = Post.new
#post.categories.build
end
def post_params
params.require(:post).permit(:title, :subtitle, :introduction, :body, :cover, :tag, category_ids: [])
end
In your form, you can use fields_for to build the form for categories.
If you set this all up, rails will handle the creation of the category when the post is created. Then you will be able to call category.posts to get all the posts with that category and you can call post.categories to get all the categories assigned to the post.
Assigning a Post to a Category can be accomplished in the create method of your PostsController. You are already passing the category_id to the controller via the params.
def create
#post = current_user.posts.new(post_params)
#category = Category.find(params[:category_id])
if #post.save && (#category.posts << #post)
redirect_to #post
else
render :new
end
end
When you are trying to show a post in a view, you should be able to access that category directly.
<%= post.category.name %>
If you allow some posts to be created without a category, you can simply not show anything, or show a "No Category" message.
# Don't show anything if the post doesn't belong to a category
<%= post.category.name if post.category.present? %>
# Show a "No Categories" message (this uses the ternary operator)
<%= post.category.present? ? post.category.name : "No Category" %>

rails 4. how to create actions using relationships between three models?

I would like to create relationships between three models: user, post and comment.
User have many posts and comments
Post have only one user and many comments
Comment have one user and one post
so i create next migrations:
class Users < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
class Posts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :content
t.integer :user_id
t.timestamps
end
end
end
class Comments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :title
t.string :content
t.integer :user_id
t.integer :post_id
t.timestamps
end
end
end
=============================================
models are next:
user.rb
class User < ActiveRecord::Base
has_many :posts
has_many :comments
end
post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
===============================================
My users_controller.rb
class UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#posts = #user.posts.paginate(page: params[:page])
#comments = #user.comments.paginate(page: params[:page])
end
def new
#user = User.new(params[:user])
end
def edit
##user = User.find(params[:id])
end
def update
##user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted."
redirect_to users_url
end
def create
#user = User.new(user_params)
if #user.save
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
now i want to create some actions for next tasks:
For posts_controller.rb
1.1 create a post by user
1.2 delete a post by user
1.3 show user post with all comments
1.4 show all user posts
class PostsController < ApplicationController
before_action :signed_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def create
#post = user.post.build(post_params)
#post = post.save
end
def destroy
#post.destroy
end
def show_user_post_with_all_comments
???
end
def show_all_user_posts
???
end
private
def post_params
params.require(:post).permit(:title, :content)
end
def correct_user
#post = current_user.posts.find_by(id: params[:id])
redirect_to root_url if #post.nil?
end
end
For comments_controller.rb
2.1 create a comment by user in post
2.2 delete a comment by user in post
2.3 show all user comments
2.4 find and show a post by user comment
class CommentsController < ApplicationController
before_action :signed_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def create
#comment = user.comment.build(comment_params)
#comment = comment.save
end
def destroy
#comment.destroy
end
def show_comment
???
end
def show_all_user_comments
???
end
def find_and_show_post_by_user_comment
???
end
private
def comment_params
params.require(:comment).permit(:content)
end
def correct_user
#comment = current_user.comments.find_by(id: params[:id])
redirect_to root_url if #comment.nil?
end
end
Pls check for correct my migrations and models and help me with creating of actions with "???" in bodies
Thank you much for your answers.
PostsController
def show_user_post_with_all_comments
#post = Post.find(params[:id]).eager_load(:comments)
end
def show_all_user_posts
#posts = current_user.posts
end
CommentsController
def show_comment
#comment = Comment.find(params[:id])
end
def show_all_user_comments
#comments = current_user.comments
end
def find_and_show_post_by_user_comment
#comment = Comment.find(params[:id]).eager_load(:post)
#post = #comment.post
end
What I've done in the past in a similar situation would be to put all this work in the UsersController and add a few new actions to it:
class UsersController < ApplicationController
...
def new_post
#user = User.find(params[:id])
end
def create_post
#user = User.find(params[:id])
if #user.update_attributes user_post_params
redirect_to somewhere_path
else
render 'new_post'
end
end
def show_post
#post = Post.find(params[:id])
# Not sure how you are implementing sessions, but say you have current_user defined
# for sessions, then your view could have a delete link conditional on
# #post.user_id == current_user.id
#comments = #post.comments
end
def show_all_posts
#user = User.find(params[:id])
#posts = #user.posts
end
def new_comment
#user = current_user
#post = Post.find(params[:id])
end
def create_comment
#user = current_user
#post = Post.find(params[:id])
#comment = Comment.new(comment_params)
if #post.update_attributes comment_params
#user.comments << #comment
if #user.save
redirect_to somewhere
else
render 'new_comment'
end
else
render 'new_comment'
end
end
def show_comments
#user = User.find(params[:id])
#comments = #user.comments
end
...
private
def user_post_params
params.require(:user).permit(:id, posts_attributes: [:title, :content])
end
def comment_params
params.require(:post).permit(:id, comments_attributes: [:content, :user_id])
end
In show_post.html.erb:
<% if #post.user_id == current_user.id %>
<%= link_to 'delete', post, method: :delete, data: { confirm: "you sure?" }
<% end %>
in your routes.rb:
get '/user/:id/new_post' => 'users#new_post', as: :user_new_post
put '/user/:id/create_post' => 'test_takers#create_post', as: :user_create_post
...and similar lines for the other actions.
Hopefully this can get you started...

Nested Resorces :forbdden attributes

I am new in rails and I am getting ActiveModel::ForbiddenAttributesError. This is my controller for nested resource:
class PostsController < ApplicationController
respond_to :html, :xml, :json
def index
#post=Post.all
end
def new
#user = User.find(params[:user_id])
#post = #user.posts.build
respond_with(#post)
end
def create
debugger
#user = User.find(params[:user_id])
#post = #user.posts.build(params[:post])
if #post.save
redirect_to user_posts_path
else
render 'new'
end
end
def post_params
params.require(:post).permit(:title, :description, {:user_ids =>[]})
end
end
If you have the following models:
post.rb
class Post < ActiveRecord::Base
belongs_to :user
end
user.rb
class User < ActiveRecord::Base
has_many :posts
end
You don't actually need to use nested attributes, just do the following in your controller:
class PostsController < ApplicationController
respond_to :html, :xml, :json
def index
#post = Post.all
end
def new
#post = Post.new
respond_with(#post)
end
def create
#user = User.find(params[:user_id])
#post = #user.posts.new(post_params) # This will automatically set user_id in the post object
if #post.save
redirect_to user_posts_path
else
render 'new'
end
end
def post_params
params.require(:post).permit(:title, :description)
end
end
Although I don't recommend that you user a user_id param in the url. Have a look at the devise gem to handle authentication.

Resources