I have a Listings Controller where Users can Create their Listings.
To prevent users to edit other users listings i just had to update every action from
Listing to current_user.listings
but with Rails 4 the controller got changed and i can't find how to set this up.
My Controller File->
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :only => [:index]
# GET /listings
# GET /listings.json
def index
#listings = Listing.all
end
# GET /listings/1
# GET /listings/1.json
def show
end
# GET /listings/new
def new
#listing = Listing.new
end
# GET /listings/1/edit
def edit
end
# POST /listings
# POST /listings.json
def create
#listing = Listing.new(listing_params)
respond_to do |format|
if #listing.save
format.html { redirect_to #listing, notice: 'Listing was successfully created.' }
format.json { render action: 'show', status: :created, location: #listing }
else
format.html { render action: 'new' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /listings/1
# PATCH/PUT /listings/1.json
def update
respond_to do |format|
if #listing.update(listing_params)
format.html { redirect_to #listing, notice: 'Listing was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
#listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
#listing = Listing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:title, :description)
end
end
Anyone knows a Solution ?
change from #new to build. So, change all #listing = Listing.new to:
#listing = current_user.listings.build
Then, in set_listing change to:
#listing = current_user.listings.find(params[:id])
Related
I installed 'google_places' gem on rails 5 but could not get it to work.When I run this code snippet:
#client = GooglePlaces::Client.new(Rails.application.secrets.places_api_key)
It gives such an error:
uninitialized constant PlacesController::GooglePlaces
And my controller:
class PlacesController < ApplicationController
before_action :set_place, only: [:show, :edit, :update, :destroy]
# GET /places
# GET /places.json
def index
#places = Place.all
end
# GET /places/nearbies
# GET /places/nearbies.json
def nearbies
#client = GooglePlaces::Client.new(Rails.application.secrets.places_api_key)
#places = #client.spots(-33.8670522, 151.1957362)
end
# GET /places/1
# GET /places/1.json
def show
end
# GET /places/new
def new
#place = Place.new
end
# GET /places/1/edit
def edit
end
# POST /places
# POST /places.json
def create
#place = Place.new(place_params)
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render :show, status: :created, location: #place }
else
format.html { render :new }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /places/1
# PATCH/PUT /places/1.json
def update
respond_to do |format|
if #place.update(place_params)
format.html { redirect_to #place, notice: 'Place was successfully updated.' }
format.json { render :show, status: :ok, location: #place }
else
format.html { render :edit }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# DELETE /places/1
# DELETE /places/1.json
def destroy
#place.destroy
respond_to do |format|
format.html { redirect_to places_url, notice: 'Place was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_place
#place = Place.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def place_params
params.require(:place).permit(:title, :address, :latitude, :longitude)
end
end
I did not solve it, I appreciate your help.
EDIT:
Its my fault. I accidentally built the google-places gem
Need to do this
class PlacesController < ApplicationController
require 'google-places'
before_action :set_place, only: [:show, :edit, :update, :destroy]
# GET /places
# GET /places.json
def index
#places = Place.all
end
I've been trying to figure this one out but I'm becoming desperate because I don't see why this isn't working.
Whatever I try, no route is matching my link and I get the following error:
Routing Error: uninitialized constant LineItemsController
My link looks like this:
<%= button_to 'Add to template', line_items_path(template_id: #template, position_id: position) %>
So the link being created is:
http://localhost:3000/line_items?position_id=2&template_id=1
routes.rb:
Rails.application.routes.draw do
resources :line_items
resources :templates
resources :positions
line_item_controller.rb
class LineItemsController < ApplicationController
before_action :set_line_item, only: [:show, :edit, :update, :destroy]
# GET /line_items
# GET /line_items.json
def index
#line_items = LineItem.all
end
# GET /line_items/1
# GET /line_items/1.json
def show
end
# GET /line_items/new
def new
#line_item = LineItem.new
end
# GET /line_items/1/edit
def edit
end
# POST /line_items
# POST /line_items.json
def create
position = Position.find(params[:position_id])
template = Template.find(params[:template_id])
#line_item = LineItem.new(position, template)
respond_to do |format|
if #line_item.save
format.html { redirect_to template_url}
format.js {#current_item = #line_item}
format.json { render action: 'show',
status: :created, location: #line_item }
else
format.html { render action: 'new' }
format.json { render json: #line_item.errors,
status: :unprocessable_entity }
end
end
end
# PATCH/PUT /line_items/1
# PATCH/PUT /line_items/1.json
def update
respond_to do |format|
if #line_item.update(line_item_params)
format.html { redirect_to #line_item, notice: 'Line item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #line_item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /line_items/1
# DELETE /line_items/1.json
def destroy
#line_item.destroy
respond_to do |format|
format.html { redirect_to line_items_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_line_item
#line_item = LineItem.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
# def line_item_params
# params.require(:line_item).permit(:position_id, :template_id)
# end
#...
end
From my understanding, my link should send a POST request that should call the create action of the line_item controller, thereby matching the route POST /line_items(.:format) line_items#create
Thanks for the help guys!
I think the issue is the filename of your controller:
line_item_controller.rb should be line_items_controller.rb
Struggling to get the create working for my nested routes in the following controller:
class BooksController < ApplicationController
before_action :set_book, only: [:show, :edit, :update, :destroy]
before_filter :load_author
# GET /books
# GET /books.json
def index
#books = #author.books.all
end
# GET /books/1
# GET /books/1.json
def show
end
# GET /books/new
def new
#book = #author.books.new
end
# GET /books/1/edit
def edit
end
# POST /books
# POST /books.json
def create
#book = #auhtor.books.new(book_params)
respond_to do |format|
if #book.save
format.html { redirect_to [#parent, #child], notice: 'Book was successfully created.' }
format.json { render :show, status: :created, location: #book }
else
format.html { render :new }
format.json { render json: #book.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /books/1
# PATCH/PUT /books/1.json
def update
respond_to do |format|
if #book.update(book_params)
format.html { redirect_to #book, notice: 'Book was successfully updated.' }
format.json { render :show, status: :ok, location: #book }
else
format.html { render :edit }
format.json { render json: #book.errors, status: :unprocessable_entity }
end
end
end
# DELETE /books/1
# DELETE /books/1.json
def destroy
#book.destroy
respond_to do |format|
format.html { redirect_to books_url, notice: 'Book was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_book
#book = Book.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def book_params
params.require(:book).permit(:name, :author_id)
end
def load_author
#author = Author.find(params[:author_id])
end
end
I am getting the following error on line #29:
undefined method `books' for nil:NilClass
Any ideas? It correctly populates the author_id field in the create view but when i click save I get this error.
I'm sure you will laugh out loud after getting solution of the issue.
You have MIS-SPELLED instance object as #auhtor. It should be #author in first line of create action.
#book = #author.books.new(book_params)
My application consists of Items. They have a status attribute that's a boolean. I added it to items by doing rails g migration AddStatusToItems status:boolean. To show the status of an item as either complete or pending, in the view, I just do
<% if status? %>
Complete
<% else %>
Pending
<% end %>
Oh yeah, I also added :status to the params hash in the controller.
It works as it should locally, but on Heroku the status just goes back to pending. Here's the log on Heroku. How can I get this working?
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show, :upvote]
# GET /items
# GET /items.json
def index
#items = Item.all.order('created_at DESC')
end
# GET /items/1
# GET /items/1.json
def show
end
# GET /items/new
def new
#item = Item.new
end
# GET /items/1/edit
def edit
end
# POST /items
# POST /items.json
def create
#item = current_user.items.new(item_params)
respond_to do |format|
if #item.save
format.html { redirect_to root_path, notice: 'Item was successfully created.' }
format.json { render action: 'show', status: :created, location: #item }
else
format.html { render action: 'new' }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
respond_to do |format|
if #item.update(item_params)
format.html { redirect_to #item, notice: 'Item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
#item.destroy
respond_to do |format|
format.html { redirect_to items_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
#item = Item.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:name, :quantity, :boughtfor, :soldfor, :user_id, :status)
end
end
I want anyone (even those not logged in) to be able to view the posts, but only the owner of the post to be able to edit or destroy the post. Currently, however, any user can edit or destroy any post. If I change
def set_pin
#pin = Pin.find(params[:id])
end
to
def set_pin
#pin = current_user.pins.find(params[:id])
end
the current user cannot edit other users' posts, but also cannot view them. Please help me out. Thanks.
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, except: [:index]
# GET /pins
# GET /pins.json
def index
#pins = Pin.all
end
# GET /pins/1
# GET /pins/1.json
def show
end
# GET /pins/new
def new
#pin = current_user.pins.new
end
# GET /pins/1/edit
def edit
end
# POST /pins
# POST /pins.json
def create
#pin = current_user.pins.new(pin_params)
respond_to do |format|
if #pin.save
format.html { redirect_to #pin, notice: 'Pin was successfully created.' }
format.json { render action: 'show', status: :created, location: #pin }
else
format.html { render action: 'new' }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /pins/1
# PATCH/PUT /pins/1.json
def update
respond_to do |format|
if #pin.update(pin_params)
format.html { redirect_to #pin, notice: 'Pin was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# DELETE /pins/1
# DELETE /pins/1.json
def destroy
#pin.destroy
respond_to do |format|
format.html { redirect_to pins_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
#pin = Pin.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description)
end
end
for edit and destroy use
def set_pin
#pin = current_user.pins.find(params[:id])
end