How can show the data related to logged in user in rails - ruby-on-rails

I am trying display the task related to logged in user but on my html page nothing show except the tag data
task_controller.rb
class TaskController < ApplicationController
def all_task
if current_user.present?
#all_task = Task.find_by_user_id(#current_user.id)
render template: 'task/allTask'
end
end
end
routes.rb
get 'all_task' => 'task#all_task'
task.erb
<p>All Task</p>
<% if user_signed_in? %>
<%#all_task.daily_task %>
<%#all_task.date %>
<%#all_task.created_at %>
<%end %>

Start by setting up an assocation between users and tasks:
class User < ApplicationRecord
# ...
has_many :tasks
end
Then setup the route and controller:
get '/user/tasks', to: 'users/tasks#index', as: :user_tasks
# app/controllers/users/tasks_controller.rb
module Users
class TasksController < ApplicationRecord
before_action :authenticate_user!
# display all the tasks belonging to the currently signed in user
# GET /user/tasks
def index
#tasks = current_user.tasks
end
private
# You don't need this if your using Devise
def authenticate_user!
unless current_user
redirect_to '/path/to/your/login',
notice: 'Please sign in before continuing'
end
end
end
end
Note that when you have a route like this that displays resources that belong to the current user you should use a callback to bail early and redirect the user to sign in instead of using if current_user.present? and giving a response which is meaningless to the user. This code should be DRY:ed into your ApplicationController (even better yet is to not reinvent the auth wheel).
You can link to the users tasks with:
<% if current_user.present? %>
<%= link_to 'My tasks', user_tasks_path %>
<% end %>
In your view you need to iterate across the returned tasks:
# app/views/users/tasks/index.html.erb
<p>All Tasks</p>
<% if #tasks.any? %>
<% #tasks.each do |task| %>
<%= task.daily_task %>
<%= task.date %>
<%= task.created_at %>
<% end %>
<% else %>
<p>You don't have any tasks.</p>
<% end %>
You can cut duplication here by using partials.

Can you make sure if the instance variable #current_user is defined? If not, try the following:
class TaskController < ApplicationController
def all_task
if current_user.present?
#all_task = Task.find_by_user_id(current_user.id)
render template: 'task/allTask'
end
end
end
instead of
class TaskController < ApplicationController
def all_task
if current_user.present?
#all_task = Task.find_by_user_id(#current_user.id)
render template: 'task/allTask'
end
end
end

Related

Faraday rails started with it

I have to show data from this website: https://baconipsum.com/json-api/ , but I don't know where to write the code of it in my app. What code do I have to write for controllers and in views?
Setup faraday:
bacon = Faraday.new("https://baconipsum.com/") do |f|
f.response :json # automatically parse responses as json
end
Send a request in the controller:
#bacon = bacon.get("api/", type: 'all-meat', sentences: 1).body # => ["Leberkas frankfurter chicken tongue."]
Use it in the view:
<% #bacon.each do |meat| %>
<p>
<%= meat %>
</p>
<% end %>
https://lostisland.github.io/faraday/usage/
Update
There are many ways to set it up. Very simple set up could look like this:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
private
# NOTE: this method will be accessible in any controller
# that inherits from ApplicationController
def baconipsum
# NOTE: memoize for a bit of performance, in case you're
# making multiple calls to this method.
#baconipsum ||= Faraday.new("https://baconipsum.com/") do |f|
f.response :json
end
end
end
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def show
#article = Article.find(params[:id])
# I'm not quite sure what you're trying to do with it;
# change this to fit your use case.
#bacon = baconipsum.get("api/", type: 'all-meat').body
end
end
# app/views/articles/show.html.erb
<% #bacon.each do |meat| %>
<p> <%= meat %> </p>
<% end %>

How to write a custom function in a model in ruby on rails?

I have a User model class I have created with Devise.
I have a role field (admin=0, user=1) in my model.
Screenshot of my database:
HTML View
<% if current_user.active_admin? %>
<%= render 'layouts/admin' %>
<% else %>
<%= render 'layouts/user' %>
<% end %>
Model
def active_admin?
#your logic here
end
I want to login. If I am an admin check role is 0 render to layouts/admin else I am a user check role is 1 render to layouts/user.
How do I write code in the model to do this?
In your user.rb file:
class User < ActiveRecord::Base
def active_admin?
role == 0
end
end
In your view:
<% if current_user.active_admin? %>
<%= render 'layouts/admin' %>
<% else %>
<%= render 'layouts/user' %>
<% end %>
As Mark says, you can just check role for 0 or 1.
Any column in your database will map directly to a method on the model.
A couple of points:
If you're using Rails 5 you'll need to inherit from ApplicationRecord rather than ActiveRecord::Base.
In newer versions of Ruby you can use the #zero? method:
class User < ApplicationRecord
def active_admin?
role.zero?
end
end
No need of adding a method for checking the roles, you can directly achieve this by below change. It will return true for anything other than 0.
<% if current_user.role? %>
<%= render 'layouts/user' %>
<% else %>
<%= render 'layouts/admin' %>
<% end %>
One way can be add an method on application controller as
def after_sign_in_path_for(resource_or_scope)
if current_user.role==0
#your admin path
else
root_path
end
end
def authenticate_admin
unless (user_signed_in? and current_user.role !=0 )
redirect_to '/users/sign_in'
end
end
add to the required controller
before_filter :authenticate_admin
layout 'admin'

Implementing a policy class using Pundit - Rails

I writing a class called AdminPolicy This class is basically trying to say whether or not a user is an admin... Right now I pass in the current_user and the current_account. I basically have a join to table between user and account and that has the admin attribute on it. Everything seems to be working fine except for this error that I'm getting undefined local variable or method 'admin_policy'. Here is my code, I can't seem to figure out what is wrong?
admin policy class
class AdminPolicy < ApplicationPolicy
attr_reader :user, :account
def initialize(user, account)
#user = user
#account = account
end
def allow_access?(user, account)
membership = account.membership_for?(user)
if membership.admin
true
else
false
end
end
end
pages controller
def admin_policy
#admin_policy ||= AdminPolicy.new(current_user, current_account)
end
dashboard.html.erb
<% if admin_policy.allow_access?(current_user, current_account) %>
<div class="admin-dashboard">
<%= render partial: "admin_dashboard" %>
</div>
<% else %>
<div class="worker-dashboard">
<%= render partial: "worker_dashboard" %>
</div>
<% end %>
Error
So its saying that admin_policy is undefined.. Any idea why this would be?
First, allow_access? doesn't need to receive parameters, so your policy should be
class AdminPolicy < ApplicationPolicy
attr_reader :user, :account
def initialize(user, account)
#user = user
#account = account
end
def allow_access?
membership = account.membership_for?(user)
if membership.admin
true
else
false
end
end
end
In your views, you can call it in this way (this is not the only way to do it)
<% if policy(Admin).allow_access? %>
<div class="admin-dashboard">
<%= render partial: "admin_dashboard" %>
</div>
<% else %>
<div class="worker-dashboard">
<%= render partial: "worker_dashboard" %>
</div>
<% end %>
Be sure to read carefully the documentation.
Heads up!
If you are inheriting from ApplicationPolicy you don't need to include attr_reader and ìnitialize method because both are defined by default in the ÀpplicationPolicy
Try this
<% if #admin_policy.allow_access?(current_user, current_account) %>
Hope this will helping you.

Undefined method link_to_edit using Draper decorator

I've got a User and Post models, which are related to each other in a classical way -- User has_many :posts and Post belongs_to :user. In my users#show, where I display a user's profile, I also have a list of all posts he has made. Also, I wanted to have links to edit and delete each post respectfully. So, I made up with this:
<% #user.posts.each do |post| %>
<h1><%= link_to post.title, post_path(post) %></h1>
<% if #user == current_user %>
<%= link_to 'Edit', edit_post_path(post) %>
<%= link_to 'Delete', post_path(post), method: :delete %>
<% end %>
<% end %>
But surely placing this logic into view results in a mess, so I decided to use Draper and write decorators for that. As we are going to check rights for posts#edit and posts#delete methods, I came up with a decorator for Post model and tried to use it in PostsController. Here it goes:
class PostDecorator << Draper::Decorator
delegate_all
def link_to_edit
if object.user == current_user
h.link_to 'Edit', h.edit_post_path(object)
end
end
def link_to_delete
if object.user == current.user
h.link_to 'Delete', h.post_path(object), method: :delete
end
end
end
Then, in my PostsController:
# ... class definition
before_action :set_post, only: [:show, :edit, :update, :destroy]
# ... other controller methods
def edit; end
def update
if #post.update(post_params)
#post.save
redirect_to post_path(#post)
else
render 'edit'
end
end
def destroy
#post.destroy
redirect_to feed_path
end
private
# Using FriendlyId gem to have neat slugs
def set_post
#post = Post.friendly.find(params[:id]).decorate
end
But every time I try to render my User profile with list of his posts, with the use of my new helpers <%= post.link_to_delete %> and <%= post.link_to_edit %> instead of that conditional mess, it just returns me the following error:
What am I doing wrong?
You probably figured this out in the meantime but here's an answer for others: You were calling #post = ....decorate in your controller but you are using #user.posts.each { |post| ... } in your view. The objects fed to that block are not decorated. Only #post is.
In your view you should have done something like #user.posts.each { |raw_post| post = raw_post.decorate } and so on. Obviously, with ERB syntax. Or #user.decorated_posts.each ... where
class User < ActiveRecord::Base
...
def decorated_posts
# this will load every post associated with the user.
# if there are a lot of them you might want to only load a limited scope of them
posts.map(&:decorate)
end
...
end

How can I only display an add review form if a user hasn't already submited a review?

Hi I'm a super beginner and working on my first app, I have a table of venues and users can add reviews to the venues. I would like to be able to hide the review form to users once they have submitted a review, to stop them from submitting more.
This is what I have now:
add review form on venue show page
<% if reviewed? %>
<%= form_for [#venue, #review], :class => 'rating_ballot' do |f| %>
<%= f.label("value_1", content_tag(:span, '1'), {:class=>"rating", :id=>"1"}) %>
<%= radio_button_tag("review[rating]", 1, :class => 'rating_button') %>
<%= f.label("value_2", content_tag(:span, '2'), {:class=>"rating", :id=>"2"}) %>
<%= radio_button_tag("review[rating]", 2, :class => 'rating_button') %>
<%= f.label("value_3", content_tag(:span, '3'), {:class=>"rating", :id=>"3"}) %>
<%= radio_button_tag("review[rating]", 3, :class => 'rating_button') %>
<%= f.label("value_4", content_tag(:span, '4'), {:class=>"rating", :id=>"4"}) %>
<%= radio_button_tag("review[rating]", 4, :class => 'rating_button') %>
<%= f.label("value_5", content_tag(:span, '5'), {:class=>"rating", :id=>"5"}) %>
<%= radio_button_tag("review[rating]", 5, :class => 'rating_button') %> <br>
<p>title: <br>
<%= f.text_field :title %></p><br>
<%= submit_tag %>
<% end %>
<% end %>
application controller
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
helper_method :reviewed?
protected
def reviewed?
true
end
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
I cant figure out what the reviewed? helper should be to allow me to do this, any help is greatly appreciated!
edit
I've added the has_reviewed helper to the application controller, it now shows this error:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Extracted source (around line #79):
76: <%= render :partial => 'reviews/review', :collection => #venue.reviews %>
77: </div>
78:
79: <% if reviewed? %>
application controller
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
helper_method :current_user
helper_method :has_reviewed
helper_method :reviewed?
protected
def reviewed?
Review.has_reviewed(#current_user.id, venue.id)
end
def has_reviewed
!Review.where(:user_id=>user,:venue_id=>venue).blank?
end
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
another edit
I've changed the reviewed? helper method to:
def reviewed?
if current_user
Review.has_reviewed(#current_user.id, #venue.id)
else
nil
end
end
but it gives undefined method `has_reviewed' for # error
schema
A venue has many reviews
A user has many reviews
A review belongs to a user and a venue
the routes looks like this:
App::Application.routes.draw do
resources :sessions
resources :users
resources :venues do
resources :reviews
end
end
Presuming you make the change as suggested by Wes, the reviewed? method would look in the database to see if this user has made a review.
The reviews table will need to have a column for the user that made the review and the venue it reviewed.
So the code would look something like this...
EDITED to reflect schema recently added
In the controller
def reviewed?
if current_user
#current_user.has_reviewed(#venue.id)
else
nil
end
end
In the User model...
class User < ...
has_many :reviews
def has_reviewed(venueid)
reviews.exists?(:venue_id => venueid)
end
...
end
Basically I think the has_reviewed is better off in the User model as the user has_many reviews, and then it can check if the user has reviewed the given venue.
I am presuming that the Model Review has a foreign key to venue called venue_id, as a Review belongs_to a Venue and that would be the standard thing.
<% unless reviewed? %>
[...]
<% end %>

Resources