Rails how to send params[:commit] value - ruby-on-rails

I am building a blog application in which I am trying to send some values like
post.id
params[:commit] (value )
So from my show action I am sending these 2 values to my edit action in my posts controller but i am unable to collect params[:commit] value ..in my case for approve it will send 'approve' and for decline it will send 'decline' but it is not sending
[posts/show.html.erb]
<div id="post_content">
<h1 class="title"><%= #post.title %></h1>
<p class="date">
Submitted <%= time_ago_in_words(#post.created_at) %> Ago
<% if user_signed_in? %>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Delete', post_path(#post), method: :delete, data: { confirm: 'Are you sure?' } %>
<%= link_to "approve",[:edit,#post] ,commit: "Approve"%>
<%= link_to "decline",[:edit,#post],commit: "decline" %>
<% end %>
</p>
<p class="body"><%= #post.body %></p>
<div id="comments">
<h2><%= #post.comments.count %> Comments</h2>
<%= render #post.comments %>
<h3>Add a comment:</h3>
<%= render "comments/form" %>
</div>
</div>
[posts_controller.rb]
class PostsController < ApplicationController
before_action :authenticate_user!
def index
#posts = Post.user_post(current_user).order('created_at DESC').paginate(:page => params[:page], :per_page => 5)
end
def new
#post = Post.new
end
def show
#post=find_params
end
def create
#post = Post.new(post_params)
#post.user = current_user
if #post.save
Post.upload(params[:post][:files],#post.id)
redirect_to #post
else
render 'new'
end
end
def edit
#post = find_params
puts "cccccccccc#{params[:commit]}"
Post.up(#post.id,params[:commit])
end
def update
#post = find_params
if #post.update(post_params)
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = find_params
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :body)
end
def find_params
Post.find(params[:id])
end
end

Change your link_to tag according to this.
<%= link_to "approve", edit_post_path(#post, commit: "Approve") %>
<%= link_to "decline", edit_post_path(#post, commit: "Decline" %>

Related

hide "edit" and "destroy" unless logged in as admin

I made Authentication in the rails blog project, but those who log in to the site, that is, admin can edit and destroy, guest user cannot edit destroy. I'm very new to rails and I don't know what to add. and how to make guest user login? guest user only read.
index.html
<div class="container">
<div class="row">
<% #articles.each do |article| %>
<div class="col-md-6">
<div class="row g-0 rounded overflow-hidden shadow-lg h-md-250">
<div class="col p-4 d-flex flex-column">
<strong class="mb-2 text-primary"><%= article.title %></strong>
<h3 class="mb-0"></h3>
<div class="mb-1 text-muted"><%= article.created_at.strftime("%d.%m.%Y %H:%M") %>
</div>
<p><%= article.text.truncate(110) %></p>
<div>
<%= link_to "Read more", article_path(article)%><br/><br/>
<tr>
<%= link_to 'Show', article_path(article),class:"btn btn-outline-success btn-sm"%>
<%= link_to 'Edit', edit_article_path(article),class:"btn btn-outline-warning btn-sm"%>
<%= link_to 'Destroy', article_path(article),class:"btn btn-outline-danger btn-sm",
method: :delete,
data: { confirm: 'Are you sure?' } %>
</tr>
</div>
</div>
</div>
</div>
<% end %>
</div>
<br/><br/>
<%= link_to 'New article', new_article_path,class:"btn btn-dark" %>
<%# sayfada show, edit, destroy butonları aktive oldu %>
</div>
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
end
articles_controller.rb
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
#article = Article.new(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)
end
end
You haven't mentioned how you implemented authentication - I am assuming you added the gem Devise by looking at your code, but anyway you will have to somehow store each user's role. For example add an admin column to your User model
rails g migration AddsAdminColumnToUsers
def change
add_column :users, :admin, :boolean, default: false, null: false
end
and then force this requirement in your views and controller
<% if current_user.admin? %>
<%= link_to 'Edit', edit_article_path(article),class:"btn btn-outline-warning btn-sm"%>
<%= link_to 'Destroy', article_path(article),class:"btn btn-outline-danger btn-sm",
method: :delete,
data: { confirm: 'Are you sure?' } %>
<% end %>
class ArticlesController < ApplicationController
def destroy
raise "unauthorized" unless current_user.admin?
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
def edit
raise "unauthorized" unless current_user.admin?
...
end
end
Many people use gems like Rolify and CanCan but for simple needs this approach can work without any gems.

Issue in my rails controller

I am having problem in my rails controller that my index, show pages won't be appearing in my server, this is my code in controller:
class GamesController < ApplicationController
def index
#games=Game.all
#render_carousel = true
end
def new
#game=Game.new
end
def create
#game=Game.new(game_params)
if #game.save
flash[:notice] = 'game created'
redirect_to games_path
else
render 'new'
end
end
def edit
#game=Game.find(params[:id])
end
def update
#game=Game.find(params[:id])
if #game.update(game_params)
flash[:notice] = 'game updated'
redirect_to games_path
else
render 'edit'
end
end
def destroy
#game=Game.find(params[:id])
#game.destroy(game_params)
flash[:notice] = 'game deleted'
redirect_to games_path
end
def show
#game=Game.find(params[:id])
end
private
def game_params
params.require(:game).permit(:name, :year, :description, :price, :category_id, :creator_id,:coverpath)
end
end
This is my index page code: I get the error in link_to line, and the error is in index and show page
<div id="page-index">
<div class="row">
<div class="col-md-3 col-sm-3">
<div class="thumbnail">
<%= image_tag('cover/un1.jpg')%>
<h4><b>Uncharted</b></h4>
<p>The Uncharted series is one of the best action adventure franchises in recent gaming history,
</p>
<%= link_to 'Read More' ,#game_path(game), class:'btn btn-primary'%>
<div>
</div>
</div>
</div>
Do this:
<%= link_to 'Read More', game_path(game), class:'btn btn-primary'%>
or, just this:
<%= link_to 'Read More', game, class: 'btn btn-primary'%>
Both should work as long as game is actually present in the database.
Update
Loop through the #games and show the each game link in your index.html.erb file:
<% #games.each do |game| %>
<%= link_to 'Read More', game_path(game), class:'btn btn-primary'%>
<% end %>

Rails: Error Messages Partial Not Rendering

I can see in my console that the erorr_messages partial I made is getting rendered, and if a comment does not pass validations, then it will not be posted, but I can't get the actual error contents to render.
Error Partial:
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(object.errors.count, "error") %>
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Comment form
<%= form_for #comment, url: comments_path do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.hidden_field :post_id, value: post.id %>
<%= f.text_area :content, size: "60x2", placeholder: "Comment on this post..." %>
<%= f.submit "Comment" %>
Post Form
<%= form_for [#user, #post] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.text_area :content, size: "60x12", placeholder: "What do you want to say?" %>
<%= f.submit "Post" %>
Users/show
<% if #user == current_user %>
<h4>Welcome <%= current_user.email %>! </h4>
<%= render "notifications" %>
<%= render 'shared/post_form' %>
<%= render 'feed' %>
<% end %>
class CommentsController < ApplicationController
def index
#comments = Comment.all
end
def new
#comment = Comment.new
#user = User.find(params[:user_id])
end
def create
#user = current_user
#comment = #user.comments.build(comment_params)
if #comment.save
flash[:success] = "Comment Posted!"
redirect_back(fallback_location: root_path)
else
flash[:danger] = "Could not post comment"
redirect_back(fallback_location: root_path)
end
end
private
def comment_params
params.require(:comment).permit(:content, :user_id, :post_id)
end
end
class PostsController < ApplicationController
def index
#posts = Post.all
#user = User.find(params[:user_id])
#comment = Comment.new
end
def new
#post = Post.new
#user = User.find(params[:user_id])
end
def create
#post = current_user.posts.build(post_params)
if #post.save
flash[:success] = "Posted!"
redirect_to user_path(current_user)
else
flash[:danger] = "Post could not be submitted"
redirect_to users_path
end
end
private
def post_params
params.require(:post).permit(:content)
end
end
In your CommentsController#create, when the save fails, rather than redirecting:
redirect_back(fallback_location: root_path)
Try staying on the same page and just rendering the "new" template:
render action: "new"
If you redirect, the browser will make a second request and #comment will get overwritten with a freshly-built Comment.
If you stay on the same page and render the "new" template, it will use the #comment instance that's already loaded and which failed to save (this instance has all the validation errors set on it).
P.S. the flash message works because that's what flash is for - a way to store messages in your session so that they survive across redirects.

How to combine a <div> with a Rails "link_to"?

I am creating a "to-do website". Users can log in and generate tasks as well as notes. The tasks work perfectly but I have some issues with notes for some reason. I don't use any partials for notes. If I use this on my index.html.erb as I did for the tasks:
<div class="notes">
<%= link_to 'New Note', new_note_path %>
<div class="note">
<div>
<%= link_to note_path(note) do %>
<%= note.content %>
<%= link_to 'X', note, :class => 'task-destroy', method: :delete, data: {confirm: 'Are you sure?'} %>
<% end %>
</div>
<div>
<%= link_to edit_note_path(note) do %>
<%= time_ago_in_words(note.updated_at) %> ago
<% end %>
</div>
</div>
</div>
I get:
"NameError in NotesController#index" - "undefined local variable or
method `note' for #..."
notes_controller.rb
class NotesController < ApplicationController
before_action :logged_in_user
before_action :set_note, only: [:show, :edit, :update, :destroy]
def index
#notes = current_user.notes
end
def show
end
def new
#note = Note.new
end
def edit
end
def create
#note = current_user.notes.new(note_params)
if #note.save
flash[:success] = "You successfully created a Note!"
redirect_to notes_path
else
render 'new_note_path'
end
end
def update
#note.update(note_params)
if #note.save
flash[:success] = "You successfully updated a Note!"
redirect_to notes_path
else
render 'edit_note_path'
end
end
def destroy
#note.destroy
flash[:success] = "You successfully deleted a Note!"
redirect_to notes_path
end
private
def set_note
#note = Note.find(params[:id])
end
def note_params
params.require(:note).permit(:content)
end
end
Question: What is wrong with my instance variable on my controller and how can I make it work?
add loop before <div class="note"> to loop through list of notes stored in #notes in your index action.
Html should look like this:
<% #notes.each do |note| %>
<div class="note">
<div>
<%= link_to note_path(note) do %>
<%= note.content %>
<%= link_to 'X', note, :class => 'task-destroy', method: :delete, data: {confirm: 'Are you sure?'} %>
<% end %>
</div>
<div>
<%= link_to edit_note_path(note) do %>
<%= time_ago_in_words(note.updated_at) %> ago
<% end %>
</div>
</div>
</div>
<% end %>
Your index.html.erb view doesn't have access to a note variable.
The instance variable from the following method is the only variable being passed to the view:
def index
#notes = current_user.notes
end
You would probably need to do something like,
<% #notes.each do |n| >
<%= link_to(n) >
<% end >

rails_autolink gem for my comments issues

I can't seem to implement this option: On my app, users can create posts and comment on posts as well. If a user wants to show a URL in either the www format or http format, how should I display that using the rails_autolink gem? I want the url to be clickable and take you to the link. I have already installed the gem and I added it to my posts controller. Another user suggested that gem to me but I do not understand how to implement it. Users create comments from the posts show template. Does the gem need to be used in the show template or the posts_controller?
this is my post show.html.erb:
<div class="page-header">
<h2>
<%= #post.title %>
<small>
posted by <%= link_to #post.creator.username %> <%= time_ago_in_words(#post.created_at) + ' ago' %>
| <%= link_to 'go to link', fix_url(#post.url) %>
<% if logged_in? && (#post.creator == current_user) %> |
<%= link_to 'edit', edit_post_path(#post) %> |
<i class="icon-user icon"></i>
<% end %>
</small>
</h2>
</div>
<h3><%= #post.description %></h3>
<%= render 'shared_partials/errors', errors_obj: #comment %>
<%= form_for [#post, #comment] do |f| %>
<%= f.text_area :body, :class=> "span4", :placeholder=> "Comment goes here", :rows => "7" %>
</br>
<div class="button">
<%= f.submit "Create a comment", class: 'btn btn-primary' %>
</div>
<% end %>
<div class="page-header">
<h4>All Comments</h4>
</div>
<% #post.newest_comments.each do |comment| %>
<div class="comments">
<h5><%= comment.body %></h5>
<li>
<small class="muted">
posted by <%= link_to comment.creator.username %> <%= time_ago_in_words(comment.created_at) + ' ago' %>
<% if logged_in? && (comment.creator == current_user) %> |
<%= link_to 'edit', edit_post_comment_path(#post, comment) %> |
<i class="icon-user icon"></i>
<% end %>
</small>
</li>
</div>
<% end %>
and my posts_controller:
require 'rails_autolink'
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :vote]
before_action :require_user, only: [:new, :create, :edit, :update, :vote]
before_action :require_creator, only:[:edit, :update]
def index
#posts = Post.page(params[:page]).order('created_at DESC').per_page(15)
end
def show
#comment = Comment.new
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.creator = current_user
if #post.save
flash[:notice] = "You created a post!"
redirect_to posts_path
else
render :new
end
end
def edit
end
def update
#post = Post.find(params[:id])
if #post.update(post_params)
flash[:notice] = "You updated the post!"
redirect_to post_path(#post)
else
render :edit
end
end
def vote
Vote.create(voteable: #post, creator: current_user, vote: params[:vote])
respond_to do |format|
format.js { render :vote } # Renders views/posts/vote.js.erb
end
end
private
def post_params
params.require(:post).permit(:url, :title, :description)
end
def set_post
#post = Post.find(params[:id])
end
def require_creator
access_denied if #post.creator != current_user
end
end
I'm not entirely sure that rails_autolink will do what you're looking to accomplish. Basically, per the documentation, the gem interpolates URLs in outputted text to a hyperlink that encloses the URL as text. By default, markup is outputted as sanitized html_safe strings:
auto_link("Go to http://www.rubyonrails.org and say hello")
# => "Go to http://www.rubyonrails.org and say hello"
You should be using it directly in your view/template and you should not need to require it in our controller. Rails typically requires gem dependencies at application load, so you don't need to include them at runtime.

Resources