I'm trying to do something like Instagram where you can see images of people you only follow. A user can follow another user and create new posts.
This is what i have for following and unfollowing in my Users controller.
def following
#user = User.find(params[:id])
current_user.mark_as_following #user
respond_to do |format|
format.html {redirect_to #user}
format.js
end
end
def unfollow
#user = User.find(params[:id])
#user.unmark :following, :by => current_user
respond_to do |format|
format.html {redirect_to #user}
format.js
end
end
Here is my my Posts controller
class PostsController < ApplicationController
load_and_authorize_resource
def show
#post = Post.find(params[:id])
end
def new
#post = Post.new
end
def create
#post.user_id = current_user.id
if #post.save
redirect_to #post
else
render :new
end
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update_attributes(update_params)
redirect_to #post
else
render :edit
end
end
private
def update_params
params.require(:post).permit(:caption, :image)
end
def create_params
params.require(:post).permit(:caption, :user_id, :image)
end
end
you can create a controller like this
class FollowingPostsController < ApplicationController
def index
#posts = current_user.following_posts
end
end
and in your User model
class User < ActiveRecord::Base
def following_posts
#assuming that following_users returns the list of following users
self.following_users.map{ |user| user.posts }.flatten(1)
end
end
Or you can get the list of posts with :
Post.where(user_id: self.following_users.ids)
Related
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
i'm getting this error for my products and user table.
--Couldn't find user without an id
def set_user
#user = User.find(params[:user_id])
end
I have nested the routes like so..
resources :users do
resources :products do
resources :reviews
end
end
and here is my products controller..
class ProductsController < ApplicationController
before_action :require_signin, except: [:index, :show]
before_action :set_user
def index
#products = #user.products
end
def show
#product = Product.find(params[:id])
end
def edit
#product = Product.find(params[:id])
end
def update
#product = Product.find(params[:id])
if #product.update(product_params)
redirect_to [#user, #product], notice: "Product successfully updated!"
else
render :edit
end
end
def new
#product = #user.products.new
end
def create
#product = #user.products.new(product_params)
#product.user = current_user
if #product.save
redirect_to user_products_path(#product, #user), notice: "Product successfully created!"
else
render :new
end
end
def destroy
#product = Product.find(params[:id])
#product.destroy
redirect_to user_products_path(#product, #user), alert: "Product successfully deleted!"
end
private
def product_params
params.require(:product).permit(:title, :description, :posted_on, :price, :location, :category)
end
def set_user
#user = User.find(params[:user_id])
end
end
All i am trying to do is associate the user and product so the product belongs_to user, and the user has_many products.
class Product < ActiveRecord::Base
belongs_to :user
has_many :reviews
class User < ActiveRecord::Base
has_secure_password
has_many :reviews, dependent: :destroy
has_many :products, dependent: :destroy
As other users have mentioned the params[:user_id] value is probably nil.
That said, you already appear to have a current_user defined in the scope of the controller. I see it referenced in the create action. I'd bet that it was set by the require_sign_in before_action. Given what I think you are trying to do, it probably makes your set_user before_action a bit redundant.
You can probably just refer to current_user in your controller anywhere you are currently using #user. Alternatively, you might set #user = current_user in the set_user before_action.
SideNote:
Looking a bit closer at your create action:
def create
#product = #user.products.new(product_params)
#product.user = current_user
if #product.save
redirect_to user_products_path(#product, #user), notice: "Product successfully created!"
else
render :new
end
end
Correct me if I'm wrong but I believe doing something like #model.association.new sets the model_id for the newly created association object so I would change the two lines
#product = #user.products.new(product_params)
#product.user = current_user
to simply be
#product = current_user.products.new(product_params)
For any action of your controller you should pass user_id param.
The reason of error is params[:user_id] equal nil
I have a rails 4 app where I am trying to create permalinks with friendly_id gem based upon a users "username". The error I receive when I try to create a permalink based upon a users username is "undefined method username=" and it points to my User_controller Here is my code so far.
Users_controller.rb
class UsersController < ApplicationController
before_action :signed_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def index
#users = User.all
end
def show
#user.username = User.friendly.find(params[:id])
end
def new
#user = User.new
end
def edit
end
def update
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def create
#user = User.new(user_params)
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user #edit_user_path(current_user)
else
render 'new'
end
end
def following
#title = "Following"
#user = User.find(params[:id])
#users = #user.followed_users.paginate(page: params[:page])
render 'show_follow'
end
def followers
#title = "Followers"
#user = User.find(params[:id])
#users = #user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def user_params
params.require(:user).permit(:name, :username, :email, :password,
:password_confirmation)
end
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
def correct_user
#user = User.friendly.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
def career_finder
end
end
User.rb
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :username, use: [:slugged, :finders]
To lookup the user by friendly_id:
def show
#user = User.friendly.find(params[:id])
end
This is covered in the readme for friendly_id
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.
I am extremely new to ruby and programming in general. In the copy, paste, and pray stage as I like to call it. I am trying to restrict access of editing posts and comments to the creator but when i create a post the user_id isn't populating in the database.
thanks in advance for the help.
routes
map.resources :user_sessions
map.resources :users
map.resources :questions, :has_one => :user, :has_many => :answers
map.login "login", :controller => "user_sessions", :action => "new"
map.logout "logout", :controller => "user_sessions", :action => "destroy"
the user model
class User < ActiveRecord::Base
acts_as_authentic
has_many :questions
has_many :answers
end
the question model
class Question < ActiveRecord::Base
validates_presence_of :question, :tag
validates_length_of :question, :minimum => 5
validates_length_of :tag, :minimum =>4
belongs_to :user
has_many :answers
end
the answer model
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
enter code here
the question controller
class QuestionsController < ApplicationController
before_filter :find_question,
:only => [:show, :edit, :update, :destroy]
# GET /questions
# GET /questions.xml
def index
#questions = Question.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #questions }
end
end
# GET /questions/1
# GET /questions/1.xml
def show
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #question }
end
end
# GET /questions/new
# GET /questions/new.xml
def new
##question = Question.new
#user = Question.new
end
# GET /questions/1/edit
def edit
end
# POST /questions
# POST /questions.xml
def create
#question = Question.new(params[:question])
##question = Question.user.new(params[:question])
if #question.save
flash[:notice] = 'Question was successfully created.'
redirect_to(#question)
else
render :action => "new"
end
end
end
# PUT /questions/1
# PUT /questions/1.xml
def update
if #question.update_attributes(params[:question])
flash[:notice] = 'Question was successfully updated.'
redirect_to(#question)
else
render :action => "edit"
end
end
# DELETE /questions/1
# DELETE /questions/1.xml
def destroy
#question.destroy
redirect_to(questions_url)
end
private
def find_question
#question = Question.find(params[:id])
end
answer controller
class AnswersController < ApplicationController
def index
#question = Question.find(params[:question_id])
#answer = #question.answers
end
def show
#question = Question.find(params[:question_id])
#answer = #question.answers.find(params[:id])
end
def new
#question = Question.find(params[:question_id])
##question = Question
#answer = #question.answers.build
##answer = Answer.new
#redirect_to questions_url(#answer.question_id)
end
def create
##question = Question.find(params[:question_id])
# #question = Question
#answer = Answer.new(params[:answer])
if #answer.save
redirect_to question_url(#answer.question_id)
else
render :action => "new"
end
end
def edit
#question = Question.find(params[:question_id])
#answer = #question.answers.find(params[:id])
end
def update
#question = Question.find(params[:question_id])
#answer = Answer.find(params[:id])
if #answer.update_attributes(params[:answer])
redirect_to question_answer_url(#question, #answer)
else
render :action => "edit"
end
end
def destroy
#question = Question.find(params[:question_id])
#answer = Answer.find(params[:id])
#answer.destroy
respond_to do |format|
format.html {redirect_to #question}
format.xml {head :ok}
end
end
end
You need to scope your model to the related object for ActiveRecord to populate foreign keys. This is easiest using a helper method. If you wanted to scope to the user:
Excerpted from one of my apps using Authlogic:
class ApplicationController < ActionController::Base
helper_method :current_user_session, :current_user
protected
def current_user_session
#current_user_session ||= UserSession.find
end
def current_user
#current_user ||= current_user_session && current_user_session.user
end
end
Then you can scope e.g. current_user.answers.build, or current_user.answers.find(params[:id]
As answers belong to users and questions. You're going to have to set the scope to whichever object makes the most sense. Assuming you decided it's the user object, you'll have to set the question_id yourself Add #answer.question = #question to your controller action. Don't get into setting foreign keys manually e.g. #answer.question_id = #question.id when ActiveRecord will happily do it for you.
Do you have a current_user that is authenticated? If not, you need one. I haven't used AuthLogic but there should be some good tutorials on how to do that.
Assuming you do have a current_user, the easiest solution would be to do something like:
def create
#answer = Answer.new(params[:answer])
#answer.user_id = current_user.id <--- add this line
if #answer.save
redirect_to question_url(#answer.question_id)
else
render :action => "new"
end
end