Ruby on Rails – admin comment approval on a blog - ruby-on-rails

I am creating a blog that has pins and comments. I am wondering how to create a system whereby the admin can approve comments on blogs before users can view them.
First I tried adding a boolean field called pinreview to my comments model:
comment.rb
class Comment < ActiveRecord::Base
belongs_to :pin
scope :approved, ->{
where(:pinreview => false)
}
scope :pending, -> {
where(:pinreview => true)
}
scope :newest, -> {
order("created_at desc")
}
end
class CommentsController < ApplicationController
def create
#pin = Pin.find(params[:pin_id])
#comment = #pin.comments.create(params[:comment].permit(:name, :body))
redirect_to pin_path(#pin)
end
def destroy
#pin = Pin.find(params[:pin_id])
#comment = #pin.comments.find(params[:id])
#comment.destroy
redirect_to pin_path(#pin)
end
end
I have defined the user types through enums:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
enum access_level: [:guest, :admin]
has_many :pins
def admin
admin?
end
def guest
guest?
end
end
And in my view I have been trying things like this:
pins/show.html.erb
...
- if current_user && current_user.admin? ? #pin.comments = Comment.all : #pin.comments = Comment.where(:approved => false)
...
The pinned post shows, but not the user comments, and when logged in as admin, no space to approve comments shows. How would I create the view for admins to approve comments and then have the comments rendered in the guest user view when approved?
Also, I should mention that comments can be made by anonymous users – a user does not have to be signed up or logged in.
Would appreciate any guidance on this. I can provide more code if required. Thanks.

Simplest way to do this is like this:
(current_user.try(admin?) ? #pin.comments : #pin.comments.approved).each do |comment|

Related

Couldn't find Suscription without an ID

I have an application with users using devise for authentication, in the user model I have added in the database a column called admin with false value by default. that way I have managed to have access as administrator to certain parts of the application.
I have a subscription model and each user when authenticated gets a free value by default. what I want to achieve is that the admin user in your user list can be able to switch from free to premium. this is the code i have and i can't get it to work.
Users Model:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
#Validaciones
validates :nombre, :apellido, presence: true
devise :database_authenticatable, :validatable, password_length: 8..128
#Relaciones
has_many :patients, dependent: :destroy
has_many :articles, dependent: :destroy
has_one :profile, dependent: :destroy
has_one :suscription, dependent: :destroy
#Creación de perfil
after_create :set_profile
def set_profile
self.profile = Profile.create()
end
#Creación de suscripcion
after_create :set_suscription
def set_suscription
self.suscription = Suscription.create()
end
end
Suscription Model:
class Suscription < ApplicationRecord
belongs_to :user
enum status: {
free: 0,
premium: 1
}
end
Users controllers:
class UsersController < ApplicationController
def index
#pagy, #users = pagy(User.order(created_at: :asc), items:12)
end
def show
#user = User.find(params[:id])
end
end
Suscriptios controller:
class SuscriptionsController < ApplicationController
before_action :set_suscription
def show
end
def edit
end
def update
#suscription = Suscription.find(params[:id]).update_params
redirect_to profile_path
flash[:notice] = "La suscripción ha sido actualizada"
end
private
def set_suscription
#suscription = (current_user.suscription ||= Suscription.create)
end
def suscription_params
params.require(:suscription).permit(:status)
end
end
Route:
#UPDATE PREMIUM
patch "suscriptions", to:"suscriptions#update", as: "user_premium"
View (Link):
<%= link_to 'Update', user_premium_path ,method: :patch %>
This should fix it:
subscriptions_controller.rb
def update
#suscription = Suscription.find(params[:id]).update(subscription_params)
redirect_to profile_path
flash[:notice] = "La suscripción ha sido actualizada"
end
view
<%= link_to 'Update', user_premium_path(id: #subscription.id, status: "premium"), method: :patch %>
One other thing that is not needed, but normally I would see something like this in a controller:
private
def set_suscription
#suscription = Suscription.find(params[:id])
end
which then makes your update method look like this:
def update
#subscription.update(subscription_params)
redirect_to profile_path
flash[:notice] = "La suscripción ha sido actualizada"
end
This is all assuming you are simply trying to update the subscription from free to premium with your link_to. I wouldn't recommend doing anything like this, because what if someone accidentally marks this? They can no longer go back to a free subscription. Maybe have a modal open that is routed to subscription edit with a drop down to select the status would be better?

Linking post to authenticated user - How do I use current_user in the controller? (devise)

I am using the Rails "Getting Started" blog post exercise, and trying to integrate with Devise for authentication and authoring of posts.
When creating an Article, the Author should be the currently logged-in user.
I am getting an error when trying to Create an Article. I know that the error is in my Articles controller, but I can't seem to figure out how to grab the current logged-in Author to kick off the creation of an Article. I believe I did the relationship properly between an Author and an Article.
Error: undefined method `articles' for nil:NilClass
Author Model:
class Author < ApplicationRecord
has_many :articles
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Articles Model:
class Article < ApplicationRecord
belongs_to :author
has_many :comments, dependent: :destroy
validates :title, presence: true,
length: { minimum: 5 }
end
Articles Controller:
class ArticlesController < ApplicationController
def index
#articles = Article.all
end
def show
#article = Article.find(params[: id])
end
def new
#article = Article.new
end
def edit
#article = Article.find(params[: id])
end
def create
#author = #current_author
#article = #author.articles.create(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def update
#article = Article.find(params[: id])
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
def destroy
#article = Article.find(params[: id])
#article.destroy
redirect_to articles_path
end
private
def article_params
params.require(: article).permit(: title,: text,: author)
end
end
Try removing the # from #current_author. With devise, current_author is a method that returns the user by session[:user_id] not an instance variable.
Also, try doing one of three things....
Change #author.articles.create(atricle_params) to #author.articles.new(atricle_params)
Move the assignment of the author to the 'new' method as so...
def new
#article = Article.new
#article.author = current_user
end
Add a hidden_field to your form...
'<%= f.hidden_field :author_id, current_user.id %>
'

i only want to display posts created by user in index page in my rails app instead of all posts

This is my posts controller:
class PostsController < ApplicationController
before_action :authenticate_user!
def index
#post = Post.all
end
def new
#post = Post.new
end
def create
#post = Post.new(set_post)
#post.user_id = current_user.id
if #post.save
redirect_to post_path(#post)
else
redirect_to new_post_path
end
end
My models:
class Post < ActiveRecord::Base
has_attached_file :image, styles: { medium: "400x400#" }
validates_attachment_content_type :image, content_type: /\Aimage
\/.*\Z/
belongs_to :user
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :posts
end
Now what I have to do is in my index action where there are all posts I need only the post of user who created it, so when user gets logged in he
should be redirected to his own posts instead of all posts. I am new to rails, any suggestion would be appreciated. I don't know what to put in index and what to add in views. I have used Devise
This would do that:
def index
#post = current_user.posts
end
Just change your controller's index method.
def index
#posts = Post.where(:user_id => current_user.id)
end
This will give you an array of posts belonging to the user logged in. And one more thing, please rename the object in index from 'post' to 'posts' since the result is not a single post.

Building a Q&A app in rails, I am a bit unsure about how to send questions to a specific user

As the title suggests, I am building a Q&A application (Like ask.fm) in Ruby on Rails, and I am having some trouble with sending the question to a specific user.
I have 3 models, a User model (from Devise), A Question model with this attribute: content:text and a Answer model with this attribute: content:text
Here are their models
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
class Question < ActiveRecord::Base
has_one :answer
belongs_to :user
end
class User < ActiveRecord::Base
has_many :questions
has_many :answers
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
And here are the migrations that I created
This one adds a user_id to the question (So I can check which user sent the question, btw this works fine)
class AddUserIdToQuestion < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
end
end
Here I tried to add a receiver (the user that would get the question) but I wont work, when I create a Question It will be equal to 'nil', when I check it out in the rails console (Check the controller to see what I did)
class AddReceiverToQuestion < ActiveRecord::Migration
def change
add_column :questions, :receiver, :integer
end
end
Here is the question controller
class QuestionsController < ApplicationController
def new
#question = Question.new
end
def create
#question = Question.new(question_params)
#question.user_id = current_user.id
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id)
end
end
I also have a user profile page where I have a form show up, here is the controller for that one
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#user_questions = #user.questions
#question = Question.new
end
def create
#user = User.find(params[:id])
#question = Question.new(question_params)
#question.receiver = #user.id #This does not work
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id, :receiver)
end
end
I really hope some of you know what I could do here, thank you :)

Create another model upon Devise User registration

I'm trying to create a Profile model upon my Users registering for the site. As I have it now the Profile model is being created upon registration with the correct foreign key. My problem lies with trying to update the Profile model after the user has gone through the Devise confirmation steps.
My users are called "artists".
### /artists/registrations_controller.rb ###
class Artists::RegistrationsController < Devise::RegistrationsController
# GET /resource/sign_up
def new
super
#profile = #artist.build_artist_profile
end
# POST /resource
def create
super
#profile = #artist.create_artist_profile(profile_params)
end
private
def profile_params
params.permit(:biography, :location, :genre, :members, :facebook_url, :twitter_url, :youtube_url, :itunes_url, :amazon_url)
end
end
### /artists/profiles_controller ###
class Artists::ProfilesController < ApplicationController
before_action :authenticate_artist!
before_action :correct_artist
before_action :set_artist
def edit
#profile = ArtistProfile.find_by(params[:artist_id])
end
def update
#profile = ArtistProfile.find_by(params[:artist_id])
if #profile.update_attributes(profile_params)
redirect_to current_artist
else
redirect_to root_url
end
end
private
def set_artist
#artist = current_artist
end
def correct_artist
#artist = current_artist
if #artist != Artist.find(params[:id])
redirect_to artist_path
end
end
def profile_params
params.require(:artist_profile).permit(:biography, :location, :genre, :members, :facebook_url, :twitter_url, :youtube_url, :itunes_url, :amazon_url)
end
end
### /artist.rb ###
class Artist < ActiveRecord::Base
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :timeoutable
has_one :artist_profile, dependent: :destroy
### /artist_profile.rb ###
class ArtistProfile < ActiveRecord::Base
belongs_to :artist
validates :artist_id, presence: true
end
I put my own code into the Devise registration controller in the create method. Upon registration the ArtistProfile model is created and populated with blank strings, which is prefect. However, if I try to edit/update the individual artist's profile only the very first artist's profile gets updated.
ie. Artist 1 signs up and profile 2 is created. Artist 1 updates Profiles 1's location to Buffalo via the edit page. Artist 2 signs up and Profile 2 is created. Artist 2 updates Profile 2's location to New York, but Profile 1's location is updated, not Profile 2's.
Is this the way to create a model upon registration, and if so, how do I fix the edit/update methods?
Or is there a better way altogether?
This line of your code is incorrect:
#profile = ArtistProfile.find_by(params[:artist_id])
A fix is to find the artist, then get the profile:
#profile = Artist.find(params[:artist_id]).artist_profile
An optimization:
#artist = Artist.find(params[:artist_id]).includes(:artist_profile)
#profile = #artist.artist_profile
Or, if your controller is receiving the artist profile id, then you can do this fix:
#profile = ArtistProfile.find(params[:artist_profile_id])

Resources