He, I have a problem with my code and I'm looking for a solution for 2 hours now. I'm new on ruby on rails ( and rails .. ) and I have this error :
NameError in PhotosController#new
uninitialized constant PhotosController::Photo
here my code so you can help me on it !
photos_controller.rb :
class PhotosController < ApplicationController
before_action :set_photo, only: [:show, :edit, :update, :destroy]
# GET /photos
# GET /photos.json
def index
#photos = Photo.all
end
# GET /photos/1
# GET /photos/1.json
def show
end
# GET /photos/new
def new
#photo = Photo.new
end
# GET /photos/1/edit
def edit
end
# POST /photos
# POST /photos.json
def create
#photo = Photo.new(photo_params)
respond_to do |format|
if #photo.save
format.html { redirect_to #photo, notice: 'Photo was successfully created.' }
format.json { render action: 'show', status: :created, location: #photo }
else
format.html { render action: 'new' }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /photos/1
# PATCH/PUT /photos/1.json
def update
respond_to do |format|
if #photo.update(photo_params)
format.html { redirect_to #photo, notice: 'Photo was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /photos/1
# DELETE /photos/1.json
def destroy
#photo.destroy
respond_to do |format|
format.html { redirect_to photos_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_photo
#photo = Photo.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def photo_params
params.require(:photo).permit(:image)
end
end
photo.rb :
class Photo < ActiveRecord::Base
has_attached_file :image
end
The page I temp to reach ( //.../photos/new ) :
new.html.erb :
<h1>New photo</h1>
and my route file :
PYL::Application.routes.draw do
get "photos/test"
get "photos/update"
get "photos/show"
get "photos/new"
resources :photos
get "photos/new"
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'photo#index'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
If you have an idea, please help me :)
You named your model class Photos instead of Photo. It should be:
class Photo < ActiveRecord::Base
has_attached_file :image
end
Related
Basically, I'm trying to update the layout of my portfolio/new form but whenever I type in 'localhost:3000/portfolios/new' I get redirected to my home page. Same with 'localhost:3000/portfolios/(:id)/edit'
My routes are below:
Rails.application.routes.draw do
#Devise Routes
devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout', sign_up: 'register' }
#homepages routes
get 'about-me', to: 'pages#about'
get 'contact', to: 'pages#contact'
# blog
resources :blogs do
member do
get :toggle_status
end
end
#portfolio
resources :portfolios, except: [:show]
get 'portfolio/:id', to: 'portfolios#show', as: 'portfolio_show'
get 'react-items', to: 'portfolios#react'
# setting root path --> ex: localhost:3000/
root to: 'pages#home'
end
Here is my controller:
class PortfoliosController < ApplicationController
before_action :set_portfolio_item, only: [:edit, :update, :show, :destroy]
layout "portfolio"
access all: [:show, :index, :react], user: {except: [:destroy, :new, :create, :update, :edit]}, site_admin: :all
def index
#portfolio_items = Portfolio.all
end
# custom scope
def react
#react_portfolio_items = Portfolio.react
end
def show
end
def new
# new portfolio item is initialized.
#portfolio_item = Portfolio.new
3.times { #portfolio_item.technologies.build }
end
def create
#portfolio_item = Portfolio.new(portfolio_params)
respond_to do |format|
if #portfolio_item.save
format.html { redirect_to portfolios_path, notice: 'Portfolio Item was successfully created.' }
else
format.html { render :new }
end
end
end
def edit
end
def update
respond_to do |format|
if #portfolio_item.update(portfolio_params)
format.html { redirect_to portfolios_path, notice: 'Portfolio Item was successfully updated.' }
else
format.html { render :edit}
end
end
end
def destroy
# destroy the record
#portfolio_item.destroy
# redirect
respond_to do |format|
format.html { redirect_to portfolios_url, notice: 'Record was removed.' }
end
end
private
def portfolio_params
params.require(:portfolio).permit(:title,
:subtitle,
:body,
technologies_attributes: [:name]
)
end
def set_portfolio_item
#portfolio_item = Portfolio.find(params[:id])
end
end
So overall I'm not sure why it's doing that. When I do rails routes I can see the correct paths but when I input them in the browser, they do not work.
Any help would be greatly appreciated.
I think you had reverted access to create/update/edit/destroy.
Remove except condition from access_all for user create/update/edit/destroy
when user trying to opening a page which doesn't has permission to view, it will be redirect_to its root_path by default.
I'm trying to build a blog using rails in c9 ubuntu setup. While I was optimizing routes, I realized that my url in browser does not change along with my actions, though everything works just fine.
The url that can be seen in the browser is actually set to display all the blogs' posts, and it does, but when I try to click on only one (in this case 'My Blog Post 1') it performs the action, but url remains the same.
However, if I type the correct url manually, it also works.
Everything is working, but my url doesn't change automatically, but I have to do it manually. In this stage I can handle that, but I'm afraid I'll have problems with that later on. This is my first time that I use cloud9 environment.
Controller:
class BlogsController < ApplicationController
before_action :set_blog, only: [:show, :edit, :update, :destroy]
# GET /blogs
# GET /blogs.json
def index
#blogs = Blog.all
end
# GET /blogs/1
# GET /blogs/1.json
def show
end
# GET /blogs/new
def new
#blog = Blog.new
end
# GET /blogs/1/edit
def edit
end
# POST /blogs
# POST /blogs.json
def create
#blog = Blog.new(blog_params)
respond_to do |format|
if #blog.save
format.html { redirect_to #blog, notice: 'Blog was successfully created.' }
else
format.html { render :new }
end
end
end
# PATCH/PUT /blogs/1
# PATCH/PUT /blogs/1.json
def update
respond_to do |format|
if #blog.update(blog_params)
format.html { redirect_to #blog, notice: 'Blog was successfully updated.' }
else
format.html { render :edit }
end
end
end
# DELETE /blogs/1
# DELETE /blogs/1.json
def destroy
#blog.destroy
respond_to do |format|
format.html { redirect_to blogs_url, notice: 'Blog was successfully destroyed.' }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_blog
#blog = Blog.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def blog_params
params.require(:blog).permit(:title, :body)
end
end
Routes:
Rails.application.routes.draw do
resources :portofolioos, except: [:show]
get 'portofolioo/:id', to: 'portofolioos#show', as: 'portofolioo_show'
get 'about', to: 'pages#about'
get 'contact', to: 'pages#contact'
resources :blogs
root to: 'pages#home'
end
View just has a form. It's pretty much scaffold, I only changed show page to display id in url and added friendly_id gem, but none of it is displayed in url, but it works just fine.
<p><%= link_to portofolio_item.title, portofolioo_show_path(portofolio_item) %></p>
I was doing something completely different with my app, when suddently my application.html.erb stopped rendering in my views. I even took back all the changes I had made and that did not fix the problem. What can have happened? I've searched everywhere and tried different things, nothing works. Everything else works fine. Here are the files with the changes.
application_controller
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_user
def initialize(attributes = {})
#name = attributes[:name]
#email = attributes[:email]
end
def createRound
#gamerounds = Gameround.all
#gameround = Gameround.new({endtime: 'John Appleseed', active: true})
respond_to do |format|
if #gameround.save
format.html { redirect_to #gameround, notice: 'Gameround was successfully created.' }
format.json { render :show, status: :created, location: #gameround }
else
format.html { render :new }
format.json { render json: #gameround.errors, status: :unprocessable_entity }
end
end
end
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def admin_user
#admin_user = User.find_by(username: 'Admin')
end
protected
def authenticate_user
if session[:user_id]
# set current user object to #current_user object variable
#current_user = User.find session[:user_id]
return true
else
redirect_to(:controller => 'sessions', :action => 'login')
return false
end
end
def save_login_state
if session[:user_id]
redirect_to(:controller => 'sessions', :action => 'profile')
return false
else
return true
end
end
end
game_session controller
class GamesessionsController < ApplicationController
before_action :set_gamesession, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user, :except => [:index, :show, :new ]
layout :application
# GET /gamesessions
# GET /gamesessions.json
def index
#gamesessions = Gamesession.all
end
# GET /gamesessions/1
# GET /gamesessions/1.json
def show
end
# GET /gamesessions/new
def new
#gamesession = Gamesession.new
unless !session[:user_id]
if !current_user.admin?
redirect_to '/play'
end
end
end
# GET /gamesessions/1/edit
def edit
end
# POST /gamesessions
# POST /gamesessions.json
def create
Gamesession.delete_all
#gamesession = Gamesession.new(gamesession_params)
createRound
end
# PATCH/PUT /gamesessions/1
# PATCH/PUT /gamesessions/1.json
def update
respond_to do |format|
if #gamesession.update(gamesession_params)
format.html { redirect_to #gamesession, notice: 'Gamesession was successfully updated.' }
format.json { render :show, status: :ok, location: #gamesession }
else
format.html { render :edit }
format.json { render json: #gamesession.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gamesessions/1
# DELETE /gamesessions/1.json
def destroy
#gamesession.destroy
respond_to do |format|
format.html { redirect_to gamesessions_url, notice: 'Gamesession was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gamesession
#gamesession = Gamesession.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gamesession_params
params.require(:gamesession).permit(:players, :flares, :aliens, :gamesetup, expansion:[], level:[])
end
end
config.routes
Rails.application.routes.draw do
resources :gamerounds do
resources :currentplayers
end
resources :gamesessions
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# Artikkel, Alien liste
resources :expansions do
resources :aliens
end
resources :users
# You can have the root of your site routed with "root"
root 'gamesessions#new'
get "signup", :to => "users#new"
get "login", :to => "sessions#login"
post "login_attempt", :to => "sessions#login_attempt"
get "logout", :to => "sessions#logout"
get "profile", :to => "sessions#profile"
get "setting", :to => "sessions#setting"
get "play", :to => "gamesessions#index"
get "aliens", :to => "aliens#index"
#match ':controller(/:action(/:id))(.:format)'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
You are defining the initialize method in your controller without calling super.
def initialize(attributes = {})
#name = attributes[:name]
#email = attributes[:email]
super
end
I have two models post and topic in my rails app
class Post < ActiveRecord::Base
#relation between topics and post
belongs_to :topic
#post is valid only if it's associated with a topic:
validates :topic_id, :presence => true
#can also require that the referenced topic itself be valid
#in order for the post to be valid:
validates_associated :topic
end
And
class Topic < ActiveRecord::Base
#relation between topics and post
has_many :posts
end
I am trying to create association between both of them.
I want multiple post corresponding to each topic
I have used nested routes
Rails.application.routes.draw do
# nested routes
resources :topics do
resources :posts
end
resources :userdetails
devise_for :users, :controllers => { :registrations => "registrations" }
My Post controller looks like
class PostsController < ApplicationController
# before_action :set_post, only: [:show, :edit, :update, :destroy]
before_filter :has_userdetail_and_topic, :only =>[:new, :create]
# GET /posts
# GET /posts.json
#for new association SAAS book
protected
def has_userdetail_and_topic
unless(#topic =Topic.find_by_id(params[:topic_id]))
flash[:warning] = 'post must be for an existing topic'
end
end
public
def new
#post = #topic.posts.build
###topic = Topic.find(params[:topic_id1])
end
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
##topic.posts << #post
##current_user = current_user.id
#current_user.posts << #topic.posts.build(params[:post])
##post = Post.new(post_params )
##post.userdetail_id = current_user.id
#Association functional between topic and post
#Class variable used
###topic.posts << #post
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:topic_id,:issue, :description, :rating, :userdetail_id)
end
end
I am trying to navigate from topics/index via code <td><%= link_to 'Write', new_topic_post_path(#topic) %> </td>
but when i try to go at localhost:3000/topics]
I am getting error
No route matches {:action=>"new", :controller=>"posts", :topic_id=>nil} missing required keys: [:topic_id]
Can any body tell me about this error, as i am new to rails please clearly specify answer.
And I have one more doubt, please tell me if i am doing association between topic and post incorrectly.I have confusion about this line of code -
#topic.posts << #post
What the error missing required keys: [:topic_id] is telling you is that you need to provide a hash with the key topic_id:
<%= link_to 'Write', new_topic_post_path(topic_id: #topic) %>
Passing a resource as to a route helper only works for the id param:
<%= link_to #topic, topic_path(#topic) %>
Is a kind of shorthand for:
<%= link_to #topic, topic_path(id: #topic.to_param) %>
Addition:
#prcu is also correct. The #topic record needs to be saved to the database. Records which are not saved do not have an id since the database assigns the id column when the record is inserted.
You also need to set the #topic instance variable in PostsController:
#topic = Topic.find(params[:id])
This is commonly done with a before filter:
before_filter :set_topic, only: [:new]
def set_topic
#topic = Topic.find(params[:id])
end
The same also need to be done in TopicsController#index.
#topic is not set or it's not persisted. You can not use topic not saved to db in this helper.
I have an issue with associating two models in my rails application: Users & Profiles. An individual user profile should be created after a new user signs up. After signing up the user, saving data into the actual profile model is not successful. I can not get it to work. Please find a detailed description below.
Here is my setup:
I use Rails 4.0.0.rc2 and ruby 2.0.0p195.
Both models are associated like this:
profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
end
user.rb
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile
before_create :build_profile
As I use the devise gemI have created a registrationscontrollerto change the after_sign_up_path:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
new_user_profile_path(:user_id => #user)
end
end
Whenever I sign up a new user the actual sign up works fine, the user is subsequently being directed to http://localhost:3000/users/42/profile/new for example. However, when I then enter the data into the profile form fields and click on submit I get the following error:
No route matches [POST] "/users/profile"
Although one could expect a routing error, you will notice a different error when looking at the actual domain:
http://localhost:3000/users//profile
In case you still want to have a look at my routes.rb please do (relevant excerpt):
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get 'signup', :to => "devise/registrations#new", as: :signup
get 'login', :to => "devise/sessions#new", as: :login
get 'logout', :to => "devise/sessions#destroy", as: :logout
end
resources :users do
resource :profile
end
However, as noted above I don't really have a routing issue. It rather seems like I have an issue with the current user_id not being properly shown in the domain, which can be related to either my actual profile form or the new action on the profiles controller.
I start my profile form on new.html.erb like this:
<%= form_for #profile, url: user_profile_path(#user) do |f| %>
My profiles_controller.rblooks like this:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
#profile = Profile.new
end
# GET /profiles/1/edit
def edit
end
# POST /profiles
# POST /profiles.json
def create
#profile = Profile.new(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to #profile, notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: #profile }
else
format.html { render action: 'new' }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
##profile = Profile.find(params[:id])
#profile = current_user.profile
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params.require(:profile).permit(:photo, :address, :zip, :city, :state, :country, :telephone, :experience, :levels, :ages, :travel, :teachinglocation, :onlineteaching, :quotation, :aboutme, :subjects, :specialties, :lessondetails, :equipment)
end
end
What do I do wrong? How can I properly ensure that a newly signed up user can properly save his profile data?
It would be so great, if you could help me out.
It appears the Profile controller is not configured with the correct url - as can be seen by the missing User ID information.
You can see all currently defined paths by running the command rake routes from the command line.
I am a beginner at RESTful design and Rails, so do not consider the following expert advice.
Try changing the location of your redirect_to in the Profile create method:
# POST /profiles
# POST /profiles.json
def create
...
format.html { redirect_to user_profile_path(#profile.user, #profile), notice: 'Profile was successfully created.' }
...
If this works, the path should also be updated in the update and delete methods. As well as the format.json sections.
For additional info about this topic see:
2.9 Creating Paths and URLs From Objects
http://guides.rubyonrails.org/routing.html