How to link_to index of another user? - ruby-on-rails

In the goals show page:
<%= link_to goals_path, class: "btn" do %>
<span class="glyphicon glyphicon-list"></span> Goals
<% end %>
but instead of being taken to my own goals_path I want to be taken to the goals_path of whichever user's goal show page I'm looking at.
goals_controller
class GoalsController < ApplicationController
before_action :set_goal, only: [:show, :edit, :update, :destroy, :like]
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
def index
if params[:tag]
#goals = Goal.tagged_with(params[:tag])
else
#accomplished_goals = current_user.goals.accomplished.order("deadline")
#unaccomplished_goals = current_user.goals.unaccomplished.order("deadline")
end
end
def show
#goal = Goal.find(params[:id])
#commentable = #goal
#comments = #commentable.comments
#comment = Comment.new
#notable = #goal
#notes = #notable.notes
#note = Note.new
#correct_user = current_user.goals.find_by(id: params[:id])
end
def new
#goal = current_user.goals.build
end
def edit
end
def create
#goal = current_user.goals.build(goal_params)
if (params[:commit] == 'conceal')
#goal.conceal = true
#goal.save
redirect_to #goal, notice: 'Goal was successfully created'
elsif
#goal.save
track_activity #goal
redirect_to #goal, notice: 'Goal was successfully created'
else
flash.now[:danger] = 'Required Field: "Enter Goal"'
render 'new'
end
end
def update
if #goal.update(goal_params)
redirect_to goals_url, notice: 'Goal was successfully updated'
else
render action: 'edit'
end
end
def destroy
#goal.destroy
redirect_to goals_url
end
def like
#goal = Goal.find(params[:id])
#goal_like = current_user.goal_likes.build(goal: #goal)
if #goal_like.save
#goal.increment!(:likes)
flash[:success] = 'Thanks for liking!'
else
flash[:error] = 'Two many likes'
end
redirect_to(:back)
end
private
def set_goal
#goal = Goal.find(params[:id])
end
def correct_user
#goal = current_user.goals.find_by(id: params[:id])
redirect_to root_url, notice: "Not authorized to edit this goal" if #goal.nil?
end
def goal_params
params.require(:goal).permit(:name, :like, :deadline, :accomplished, :tag_list, :comment, :private_submit)
end
end
Please let me know if you need further explanation or code to help you help me :-]

If you have a target user defined (or have a way to access a user's id), you can do something like:
<% link_to goals_path(user_id: #goal.user_id) do %>
<span class="glyphicon glyphicon-list"></span> Goals
<% end %>
Then you can modify your index method to handle a user_id param:
def index
if params[:tag]
#goals = Goal.tagged_with(params[:tag])
elsif params[:user_id]
#goals = User.find(params[:user_id]).goals
else
#accomplished_goals = current_user.goals.accomplished.order("deadline")
#unaccomplished_goals = current_user.goals.unaccomplished.order("deadline")
end
end
This should render a particular user's goals if their id is passed in as a param. Hope this helps!

You could also just take a completely different route, and be a little more REST-ful about grabbing users/:user_id/goals, and add it as a route in your routes.rb
get "/users/:user_id/goals", to: "goals#user_goals", as: "user_goals"
and update your button to have
<% link_to user_goals_path(#goal_user) ... %>
and then add the goals#user_goals method
def user_goals
#goals = Goal.find_by({user_id: params[:user_id]})
render :index # or some other view
end

Related

No route matches {:action=>"create", :controller=>"reviews", :id=>"2", :user_id=>#<Profile id: 2...} missing required keys: [:profile_id]

I am working on user_profile_reviews and have got stuck. I have 3 models for now, and I know, that doing a separate model for a profile wasn't really a great idea, but since all my routes depend on this structure, meaning the links in all the views also, I decided not to change it.
To give you a clearer understanding:
Rails.application.routes.draw do
devise_for :user, controllers: { omniauth_callbacks: 'users/omniauth_callbacks', registrations: "users/registrations" }
resources :users do
resources :profiles do
resources :reviews, only: [:new, :create]
end
end
root 'home#index'
end
Here are my controllers:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
def index
#profiles = Profile.all
end
def show
#user = User.find(params[:user_id])
#profile = Profile.find(params[:id])
#reviews = Review.where("profile_id = ?", params[:id])
end
def new
#user = User.find(params[:user_id])
end
def edit
#profile = Profile.find(params[:id])
end
def create
#profile = current_user.build_profile(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to user_profile_path(current_user.id, current_user.profile.id), notice: 'Profile was successfully created.' }
format.json { render :show, status: :created, location: #profile }
else
format.html { render :new }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to user_profile_path(current_user.id, current_user.profile.id), notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_profile
#profile = Profile.find(params[:id])
end
def profile_params
params.permit(:about, :rating, :avatar)
end
end
Reviews
class ReviewsController < ApplicationController
before_filter :set_profile
before_filter :set_review, only: [:new, :create]
def new
#review = Review.new
end
def create
#profile = Profile.find(params[:profile_id])
#review = #profile.reviews.build(review_params)
#review.user_id = current_user.id
if #review.save
redirect_to #profile
else
redirect_to #profile, notice: "Error saving"
end
end
private
def review_params
params.permit(:content, :rating)
end
def set_pfofile
#profile = Profile.find(params[:profile_id])
end
def set_review
#profile = Profile.find(params[:id])
end
end
So now, I am trying to create a form for reviews, which I am then rendering in Profiles#show, and getting the mistake above.
<div class="submit-review">
<%= form_for [#review, :url => user_profile_reviews_path(#profile)] do |f| %>
<label for="review">How was your experience?</label><br>
<%= f.label :rating %>
<%= f.select :rating, options_for_select([["Please select one", ""], 5, 4, 3, 2, 1]) %>
<%= f.input :content, placeholder:"Please enter your feedback here" %>
<%= f.submit "Submit your review", class: "btn btn-default" %> <br><br>
<% end %>
Showing ... /_form.html.erb where line #2 raised:
No route matches {:action=>"create", :controller=>"reviews", :id=>"2", :user_id=>#<Profile id: 2, about: "lena", rating: 3, created_at: "2019-11-22 21:27:03", updated_at: "2019-11-22 21:27:03", user_id: 2>}, missing required keys: [:profile_id]
But, as I see, it gets to the profile, I am onto, so I don't understand what's the issue here.
Something wrong with the syntax, try this
= form_for([#profile.user, #profile, #review], :url => user_profile_reviews_path(#profile.user, #profile)) do |f|
Since your resources are nested, you need to pass user, profile and then review as the first argument in form_for
Suggestion: Looking at your code, you don't even need user_id, you can avoid nesting profile and review under user in routes.
Hope that helps!
Ok, this worked perfectly for solving the described problem with missing id.
form_for([#profile.user, #profile, #review], :url => user_profile_reviews_path(#profile.user, #profile)) do |f|
I was getting another error though:
First argument in form cannot contain nil or be empty
I saw then, that in my Profile#show I wasn't defining #review. Only reviews. So I did it this way:
def show
#user = User.find(params[:user_id])
#profile = Profile.find(params[:id])
#review = Review.new
#reviews = Review.where("profile_id = ?", params[:id])
end
I can now finally go to profile and there is a review window, which is great! I can't save the reviews though, as another error is showing up. But that's different case. Thank you so much!

Displaying all microposts in a select box

The following code creates a select box
<%= select_tag "microposts", options_from_collection_for_select(#microposts, "id", "name"), { :prompt => 'All microposts' } %>
I want to show all the microposts in a select box, but i get the following error
NoMethodError in Managments#edit
undefined method `map' for nil:NilClass
Did you mean? tap
Can someone explain to me how to display all the microposts in a select box?
controller
class ManagmentsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def index
#managments = current_user.managments
#micropost = current_user.microposts.build
end
def show
#microposts = Micropost.paginate(page: params[:page])
#managment = Managment.find_by(id: params[:id])
if !#managment
raise ActionController::RoutingError.new('Not Found')
end
#user = #managment.user
end
def new
#user = User.new
#managment = Managment.new
end
def edit
#managment = Managment.find(params[:id])
end
def create
#managment = current_user.managments.build(managment_params)
if #managment.save
flash[:success] = "Managment created!"
redirect_to #managment
else
#feed_items = current_user.feed.paginate(page: params[:page])
render 'new'
end
end
def update
#managment = Managment.find(params[:id])
if #managment.update(managment_params)
redirect_to #managment
else
render 'edit'
end
end
def destroy
#managment.destroy
flash[:success] = "Managment deleted"
redirect_to managments_path
end
private
def managment_params
params.require(:managment).permit(
:title, :budget,
:procent1, :procent2, :procent3, :procent4,
:procent5, :procent6, :procent7,
:procent8, :procent9, :procent10,
:procent11, :procent12, :result1,
:result2, :result3, :objectivesname1,
:objectivesname2, :objectivesname3,
:lowprocent1, :lowprocent2, :lowprocent3,
:medprocent1, :medprocent2, :medprocent3,
:highprocent1, :highprocent2, :highprocent3,
:lowobjectives1, :lowobjectives2, :lowobjectives3,
:medobjectives1, :medobjectives2, :medobjectives3,
:highobjectives1, :highobjectives2, :highobjectives3
)
end
def correct_user
#managment = current_user.managments.find_by(id: params[:id])
redirect_to managments_path if #managment.nil?
end
end
The Answer to the question can be find in the comments
def edit
#managment = Managment.find(params[:id])
#microposts = Micropost.paginate(page: params[:page])
end

How to render polymorphic comment partial in feed?

I created a feed following http://railscasts.com/episodes/406-public-activity?view=asciicast.
In that feed I'd like it to say,
"User Name" added/updated value "Value Name" with the comment "Comment Content".
This partial creates the "Value Name" part:
views/public_activity/comment/_create.html.erb
added value
<% if activity.trackable %>
<b><%= link_to activity.trackable.name, activity.trackable %></b>
<% else %>
which has since been removed
<% end %>
This partial creates the "Comment Content" part:
views/public_activity/valuation/_create.html.erb
with the comment
<% if activity.trackable %>
<%= link_to activity.trackable.content %>
<% else %>
which has since been removed
<% end %>
If I add name or content to either one of the partials I am given an undefined method error message. What code would I need to add to their controllers or application controller to make something like this work?
Ideally, with the comment "Comment Content". would only be generated in instances where a comment is created so that, with the comment, wouldn't be left hanging.
class CommentsController < ApplicationController
before_action :load_commentable
before_action :set_comment, only: [:show, :edit, :update, :destroy]
before_action :logged_in_user, only: [:create, :destroy]
def index
#comments = #commentable.comments
end
def new
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(comment_params)
if #comment.save
#comment.create_activity :create, owner: current_user
redirect_to #commentable, notice: "comment created."
else
render :new
end
end
def edit
#comment = current_user.comments.find(params[:id])
end
def update
#comment = current_user.comments.find(params[:id])
if #comment.update_attributes(comment_params)
redirect_to #commentable, notice: "Comment was updated."
else
render :edit
end
end
def destroy
#comment = current_user.comments.find(params[:id])
#comment.destroy
#comment.create_activity :destroy, owner: current_user
redirect_to #commentable, notice: "comment destroyed."
end
private
def set_comment
#comment = Comment.find(params[:id])
end
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
def comment_params
params.require(:comment).permit(:content, :commentable)
end
end
class ValuationsController < ApplicationController
before_action :set_valuation, only: [:show, :edit, :update, :destroy]
before_action :logged_in_user, only: [:create, :destroy]
def index
if params[:tag]
#valuations = Valuation.tagged_with(params[:tag])
else
#valuations = Valuation.order('RANDOM()')
end
end
def show
#valuation = Valuation.find(params[:id])
#commentable = #valuation
#comments = #commentable.comments
#comment = Comment.new
end
def new
#valuation = current_user.valuations.build
end
def edit
end
def create
#valuation = current_user.valuations.build(valuation_params)
if #valuation.save
redirect_to #valuation, notice: 'Value was successfully created'
else
#feed_items = []
render 'pages/home'
end
end
def update
if #valuation.update(valuation_params)
redirect_to #valuation, notice: 'Value was successfully updated'
else
render action: 'edit'
end
end
def destroy
#valuation.destroy
redirect_to valuations_url
end
private
def set_valuation
#valuation = Valuation.find(params[:id])
end
def correct_user
#valuation = current_user.valuations.find_by(id: params[:id])
redirect_to valuations_path, notice: "Not authorized to edit this valuation" if #valuation.nil?
end
def valuation_params
params.require(:valuation).permit(:name, :private_submit, :tag_list, :content, :commentable, :comment)
end
end
class ApplicationController < ActionController::Base
include PublicActivity::StoreController
#before_action :load_todays_habits
before_action :set_top_3_goals
before_action :randomize_value
before_action :set_stats
protect_from_forgery with: :exception
include SessionsHelper
def set_top_3_goals
#top_3_goals = current_user.goals.unaccomplished.top_3 if current_user
end
def randomize_value
#sidebarvaluations = current_user.valuations.randomize if current_user
end
def set_stats
#quantifieds = Quantified.joins(:results).all
#averaged_quantifieds = current_user.quantifieds.averaged if current_user
#instance_quantifieds = current_user.quantifieds.instance if current_user
end
hide_action :current_user
private
#def load_todays_habits
# #user_tags = current_user.habits.committed_for_today.tag_counts if current_user
# #all_tags = Habit.committed_for_today.tag_counts if current_user
#end
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
end
Thank you so much for your time.

Using a Partial, How to Create a Multi Controller ROOT ROUTE?

How can we make the root route provide: habits, valuations, goals, quantifieds (not just valuations as it currently is)?
And to make matters more difficult how can we only show #unaccomplished_goals and not #accomplished_goals when including the goals controller in the root route?
The root route would show this in 1 view:
Habits Table
Valuations Table
Unaccomplished Goals Table
Quantifieds Table
I was told I need to use a partial to share code across the application. How can we do this so that the root route could lead to something like "home"?
routes
Rails.application.routes.draw do
resources :habits
resources :goals
resources :valuations
resources :quantifieds
resources :results
devise_for :users
root 'valuations#index'
get "about" => "pages#about"
get 'tags/:tag', to: 'valuations#index', as: :tag
end
controllers
class HabitsController < ApplicationController
before_action :set_habit, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#habits = Habit.all.order("date_started DESC")
#habits = current_user.habits
end
def show
end
def new
#habit = current_user.habits.build
end
def edit
end
def create
#habit = current_user.habits.build(habit_params)
if #habit.save
redirect_to #habit, notice: 'Habit was successfully created.'
else
render action: 'new'
end
end
def update
if #habit.update(habit_params)
redirect_to #habit, notice: 'Habit was successfully updated.'
else
render action: 'edit'
end
end
def destroy
#habit.destroy
redirect_to habits_url
end
private
def set_habit
#habit = Habit.find(params[:id])
end
def correct_user
#habit = current_user.habits.find_by(id: params[:id])
redirect_to habits_path, notice: "Not authorized to edit this habit" if #habit.nil?
end
def habit_params
params.require(:habit).permit(:missed, :left, :level, :date_started, :trigger, :action, :target, :positive, :negative, :committed => [])
end
end
class ValuationsController < ApplicationController
before_action :set_valuation, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
if params[:tag]
#valuations = Valuation.tagged_with(params[:tag])
else
#valuations = Valuation.order('RANDOM()')
end
end
def show
end
def new
#valuation = current_user.valuations.build
end
def edit
end
def create
#valuation = current_user.valuations.build(valuation_params)
if #valuation.save
redirect_to #valuation, notice: 'Value was successfully created'
else
render action: 'new'
end
end
def update
if #valuation.update(valuation_params)
redirect_to #valuation, notice: 'Value was successfully updated'
else
render action: 'edit'
end
end
def destroy
#valuation.destroy
redirect_to valuations_url
end
private
def set_valuation
#valuation = Valuation.find(params[:id])
end
def correct_user
#valuation = current_user.valuations.find_by(id: params[:id])
redirect_to valuations_path, notice: "Not authorized to edit this valuation" if #valuation.nil?
end
def valuation_params
params.require(:valuation).permit(:name, :tag_list)
end
end
class GoalsController < ApplicationController
before_action :set_goal, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#goals = Goal.all.order("deadline")
#accomplished_goals = current_user.goals.accomplished
#unaccomplished_goals = current_user.goals.unaccomplished
end
def show
end
def new
#goal = current_user.goals.build
end
def edit
end
def create
#goal = current_user.goals.build(goal_params)
if #goal.save
redirect_to goals_url, notice: 'Goal was successfully created'
else
render action: 'new'
end
end
def update
if #goal.update(goal_params)
redirect_to goals_url, notice: 'Goal was successfully updated'
else
render action: 'edit'
end
end
def destroy
#goal.destroy
redirect_to goals_url
end
private
def set_goal
#goal = Goal.find(params[:id])
end
def correct_user
#goal = current_user.goals.find_by(id: params[:id])
redirect_to goals_path, notice: "Not authorized to edit this goal" if #goal.nil?
end
def goal_params
params.require(:goal).permit(:name, :deadline, :accomplished)
end
end
class QuantifiedsController < ApplicationController
before_action :set_quantified, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#quantifieds = Quantified.joins(:results).all
#averaged_quantifieds = current_user.quantifieds.averaged
#instance_quantifieds = current_user.quantifieds.instance
end
def show
end
def new
#quantified = current_user.quantifieds.build
end
def edit
end
def create
#quantified = current_user.quantifieds.build(quantified_params)
if #quantified.save
redirect_to quantifieds_url, notice: 'Quantified was successfully created'
else
render action: 'new'
end
end
def update
if #quantified.update(quantified_params)
redirect_to quantifieds_url, notice: 'Goal was successfully updated'
else
render action: 'edit'
end
end
def destroy
#quantified.destroy
redirect_to quantifieds_url
end
private
def set_quantified
#quantified = Quantified.find(params[:id])
end
def correct_user
#quantified = current_user.quantifieds.find_by(id: params[:id])
redirect_to quantifieds_path, notice: "Not authorized to edit this goal" if #quantified.nil?
end
def quantified_params
params.require(:quantified).permit(:categories, :name, :metric, :result, :date, results_attributes: [:id, :result_value, :date_value, :_destroy])
end
end
If we need to work with other files:
Github: https://github.com/RallyWithGalli/ruletoday
Or I could add them here.
Thanks for your expertise =]

How to set a users post id to their post

I'm having issues associating a users status post to them, I also can't get it to show on their account.
This is in my users_controller
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
after_action :signed_in_after_register, only: :create
def index
#users = User.all
end
def profile
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts
end
def _nav
#user = User.find(session[:user_id])
end
def destroy
#user = User.find(session[:user_id])
end
def welcome
#user = User.find(session[:user_id])
end
def show
#user = Post.first.update_attributes(user_id: 1)
#post = Post.first.update_attributes(#signed_in_user)
end
def new
#post = Post.new(params[:post_id])
#user = User.new
end
def edit
end
def create
#post.user = current.user
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to profile_path, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_user
#user = User.find(params[:id])
end
def signed_in_after_register
session[:user_id] = #user.id
end
def user_params
params.require(:user).permit(:name, :password, :password_confirmation, :email, :age, :profile_picture, :post)
end
end
This is in my posts_controller
class PostsController < ApplicationController
def index
#posts = Post.all.order('created_at DESC')
end
def new
#post = Post.new
end
def create
#post = #signed_in_user
#post = Post.new(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
def show
#post = Post.find(params[:id])
#signed_in_user = session[:user_id]
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:body))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:body)
end
end
This is the profile.html.erb page that I want the signed_in_users most recent post to be returned to
<%- #posts.each do |post| %>
<div class="post_wrapper">
<h2 class="title"><%= link_to post.body, post %></h2>
<p class="date"><%= post.created_at.strftime("%B, %d, %Y") %> </p>
</div>
<% end %>
This is in my routes
Rails.application.routes.draw do
root 'welcome#welcome'
get 'login' => 'sessions#login', :as => :login
get 'profile' => 'users#profile', :as => :profile
post 'logging/user' => 'sessions#create'
get 'logout' => 'sessions#destroy', :as => :logout
get 'about' => 'about'
resources :users
resources :posts
get 'index' => 'posts#index'
get 'register' => 'users#new', :as => :register
Just to clear the question up a bit more and be very specific, I want it to be exactly like a status post that Facebook offers, You write it, It post, It shows on your profile. That's it, I have no problems with Writing, Posting and it saving. It just doesn't show on the profile page of the user that created it.
run this command in your terminal:
rails generate migration AddUserRefToPosts user:references
in your user model:
class User < ActiveRecord::Base
has_many :posts
...
end
3.in post controller
def create
#post = Post.new(post_params)
#post.user_id = #signed_in_user.id
if #post.save
redirect_to #post
else
render 'new'
end
end
Try this
def create
#post = #signed_in_user.posts.build(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
Your create action should look like this
def create
#post = Post.new(post_params)
#post.user_id = #signed_in_user.id
if #post.save
redirect_to #post
else
render 'new'
end
end

Resources