When I create an event on the users show page I want it to redirect back to the users show page if it indeed submitted correctly. Is there anyway I can do that here is my Events controller:
class EventsController < ApplicationController
def show
#event = Event.find(params[:id])
#songs = #event.songs.paginate(page: params[:page])
end
def create
#event = current_user.events.build(event_params)
if #event.save
flash[:success] = "Event Created!"
redirect_to 'user#show'
else
render 'welcome#index'
end
end
def destroy
end
private
def event_params
params.require(:event).permit(:name, :partycode)
end
end
Redirect to the user path and pass in the User ID.
redirect_to user_path(current_user.id)
Yes you can, but you'll need to use the actual path eg instead of redirect_to 'user#show' user:
redirect_to user_path(#event.user)
Related
So as you all can see in the screen shot below in my blog form when I click submit when creating a new blog the parameters get sent but never actually get inserted into the MySQL command. Which you can see the post in the background is empty except for the Timestamp.
Now with that being said this same form is used for my Edit Blog page. My form is a partial rendered in the new blog page and the edit blog page. So if I go edit that same blog page that was created with no input up submit of the edit's the parameters actually go through and then the blog post will show will all the information from your edits.
class PostsController < ApplicationController
before_action :find_post, only: [:edit, :update, :show, :delete]
# Index action to render all posts
def index
#posts = Post.all
end
# New action for creating post
def new
#post = Post.new
end
# Create action saves the post into database
def create
#post = Post.new
if #post.save(post_params)
flash[:notice] = "Successfully created post!"
redirect_to post_path(#post)
else
flash[:alert] = "Error creating new post!"
render :new
end
end
# Edit action retrives the post and renders the edit page
def edit
end
# Update action updates the post with the new information
def update
if #post.update_attributes(post_params)
flash[:notice] = "Successfully updated post!"
redirect_to post_path(#post)
else
flash[:alert] = "Error updating post!"
render :edit
end
end
# The show action renders the individual post after retrieving the id
def show
end
# The destroy action removes the post permanently from the database
def destroy
if #post.destroy
flash[:notice] = "Successfully deleted post!"
redirect_to posts_path
else
flash[:alert] = "Error updating post!"
end
end
private
def post_params
params.require(:post).permit(:strain, :straintype, :style, :light, :temp, :breeder, :private, :notes, :nutrients)
end
def find_post
#post = Post.find(params[:id])
end
end
I just don't understand why the edit saves correctly but no the initial submit.
I think maybe it should be .create(post_params) instead of .new
http://guides.rubyonrails.org/active_record_basics.html#create
Rails: Difference between create and new methods in ActiveRecord?
Im using a gem called MetaInspector to scrape data from different websites. Im building a site where i can collect data from different sites but am having trouble setting up. I have a model called site with a title and a url both strings. When i create a new "site" the name will come out as example.com/"sitename" and in there i would like to have the data just from that site. I kinda have an idea to this by adding page = MetaInspector.new to the new method but cant see how i can set a url in there.
I can show my controller and other info if needed.
Controller
class Admin::SitesController < Admin::ApplicationController
def index
#sites = Site.all
end
def show
#site = Site.friendly.find(params[:id])
end
def edit
#site = Site.friendly.find(params[:id])
end
def update
#site = Site.friendly.find(params[:id])
if #site.update(site_params)
redirect_to admin_path
else
render :edit
end
end
def destroy
#site = Site.friendly.find(params[:id])
#site.destroy
if #site.destroy
redirect_to admin_path
end
end
def new
#site = Site.new
end
def create
#site = Site.new(site_params)
if #site.save
redirect_to admin_path
else
render :new
end
end
private
def site_params
params.require(:site).permit(:title, :url)
end
end
If I understand correct you want to show the metainfo for a Site you have added. You could put that code in the show action of the controller:
def show
#site = Site.friendly.find(params[:id])
#page = MetaInspector.new(#site.url)
end
And update the show.html.erb template to display info about #page, ie:
<%= #page.title %>
I keep getting a variety of error while trying to create and show errors in a simple Rails blog I'm trying to create.Let me know if you see anything obvious or if you need me to post more code as I've tried a number of things but to no avail. Thanks
The browser is giving me this error
Couldn't find User without an ID
in my "logged_in?" method which shows
def logged_in?
#current_user ||= User.find(session[:user_id])
end
Sessions Controller
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
flash[:success] = "You are logged in"
redirect_to root_path
else
render action: 'new'
flash[:error] = "There was a problem logging in. Please check your email and password"
end
end
end
def index
#users = User.all
end
def show
end
def new
#user = User.new
end
def edit
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
flash[:notice] = "You have registered, please login"
redirect_to login_path
else
render :new
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 { head :no_content }
else
format.html { render action: '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 }
format.json { head :no_content }
end
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
end
Articles Controller
class ArticlesController < ApplicationController
http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]
def new
#article = Article.new
end
def index
#article = Article.all
end
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def edit
#article = Article.find(params[:id])
end
def update
#article = Article.find(params[:id])
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
def show
#article = Article.find(params[:id])
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, :image)
end
end
Application Helper
module ApplicationHelper
def logged_in?
#current_user ||= User.find(session[:user_id])
end
end
The problem you're facing is that session[:user_id] is nil. Usually a method which sets current user is called current_user. The logged_in? is not a good name for a method setting an user instance, because one would expect that a method ending with a question mark would return a true or false. And not an user instance.
Also, setting the current user is usually done with a before_filter. Additionally, you want to skip such before filter for action where you're setting the current user (i.e the current_user doesn't exist yet)
Finally, I would rather fail gracefully, if user is not found. You can achieve this by changing your code to User.find_by_id(session[:user_id])
While the user is not loggued, session[:user_id] is nil, and so User.find(session[:user_id]) generates the error. The method should be like this:
def logged_in?
#current_user ||= User.find(session[:user_id]) if session[:user_id].present?
end
Why would the logged_in? helper method try to assign a value to #current_user? I think that is a bad logic, it should just return a boolean result without modifying such a central instance. This is a proper way to do that:
def logged_in?
#current_user.nil? ? false : true
end
The responsibility of setting the #current_user falls to a method that you should place in application_controller.rb and make it a before_action so that it's executed before any controller action is triggered, that is:
# app/controllers/applicaton_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_action :authenticate_user
# Your actions here
..
..
#
private
def authenticate_user
#current_user ||= User.find(session[:user_id]) if session[:user_id].present?
end
end
What's the best way to check if the current object belongs to the current user?
I want to only allow the power of deletion to the owner, but I'm struggling to build a controller function to accomplish this.
before_filter :signed_in_user, only: [:create]
before_filter :correct_user, only: [:edit, :update, :destroy]
...
def destroy
#event = Event.find(params[:id])
if #event.present?
#event.destroy
end
redirect_to root_path
end
private
def signed_in_user
unless signed_in?
store_location
redirect_to signin_path, notice: "Please sign in."
end
end
def correct_user
#event = current_user.events.find_by_id(params[:id])
rescue
redirect_to root_path
end
My current def correct_user allows any logged in user to make deletions.
Your correct_user method is already doing what you need to do: fetching the event with current_user.events.find. You can just delete the event-finding code from your destroy method and it should work correctly.
When I wrote my comment you had yet to added the destroy action code. Look carefully at the correct_user method:
def correct_user
#event = current_user.events.find_by_id(params[:id])
rescue
redirect_to root_path
end
Right there you are retrieving the event and storing it in an instance variable. More so, you are retrieving the event through the current_user. So it's scoped to the current_user, and only events that are owned by the current_user are exposed.
#event = current_user.events.find_by_id(params[:id])
Remember, correct_user is set in a before_filter, so it runs before the destroy action.
So, by the time the request gets to the destroy action, the event is already stored in an instance variable (#event). So there is already an event object for you to work with. You can reference that. There is no need to retrieve it again.
def destroy
#event = Event.find(params[:id]) #<- This line is redundant (and dangerous in this case)
... # snip
end
Change the destroy method to this.
def destroy
redirect_to root_path if #event.destroy
end
I was just about to add similar functionality! You have to check if the current user is signed in, and if their ID = the user_id of the object.
Something like
event = Event.find(params[:id])
if event.user_id == current_user.id
event.destroy
else
redirect_to :root, :notice => "You do not have permissions."
end
Please help me try and understand what is happening here:
I need to approve a nested snippet but when I do it says it cannot find book. I think it may be an issue with the routes because the URL in the browser doesn't match the rake routes.
If someone could hold my hand and explain this as you would to a child :)
Couldn't find Book without an ID
Below is the controller with snippets#approve and the before_filter.
class SnippetsController < ApplicationController
before_filter :authenticate_user!
before_filter :find_book
def create
#raise params.inspect
#snippet = #book.snippets.create(params[:snippet])
#snippet.user = current_user
if #snippet.save
redirect_to #book
flash[:success] = "Snippet submitted and awaiting approval."
else
flash[:base] = "Someone else has submitted a snippet, please try again later"
redirect_to #book
end
end
def approve
#raise params.inspect
#snippet = #book.snippets.find(params[:id])
#snippet.update_attribute(:approved, true)
redirect_to admins_path
end
def edit
#snippet = #book.snippets.find(params[:id])
end
def update
#snippet = #book.snippets.find(params[:id])
respond_to do |format|
if #snippet.update_attributes(params[:snippet])
format.html { redirect_to #book, notice: 'Comment was successfully updated.' }
else
format.html { render action: "edit" }
end
end
end
private
def find_book
#raise params.inspect
#book = Book.find(params[:book_id])
end
end
Now I understand that since I'm doing a post my rake routes says this.
/books/:book_id/snippets/:id(.:format)
Here is the routes for the custom route:
active_snippet POST /snippets/:id/activate(.:format)
This is my custom routes for book && snippet :approval
post "books/:id/activate" => "books#approve", :as => "active_book"
post "snippets/:id/activate" => "snippets#approve", :as => "active_snippet"
I've currently got this in my browser ../snippets/2/activate
Erm.... Not sure if I'm thinking correctly.
You're sending a POST request to snippets/:id/activate which calls snippets#approve.
There is a before_filter on the entire SnippetsController that calls find_book which executes #book = Book.find(params[:book_id]). Because your path is snippets/:id/activate, params[:book_id] is nil and hence you are getting that error.
You need to either change your snippets#approve path to include the book_id, or pass the book_id as a POST param so that your before filter has access to it.