Form error on Rails (Without Scaffold) - ruby-on-rails

Gem file :
source 'https://rubygems.org'
ruby "2.3.1"
gem 'rails', '4.2.3'
gem 'bootstrap-sass', '~> 3.3.6'
gem 'font-awesome-rails', '4.3.0.0'
gem 'sass-rails', '~> 5.0.4'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
group :doc do
gem 'sdoc', require: false
end
group :development, :test do
gem 'byebug', platform: :mri
gem 'sqlite3'
end
group :development do
gem 'web-console'
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
group :production do
gem 'unicorn'
gem 'pg'
gem 'rails_12factor'
end
gem 'simple_form', '~> 3.2', '>= 3.2.1'
gem 'haml', '~> 4.0', '>= 4.0.7'
Controller: (rails g controller Academy/Student)
class Academy::StudentController < ApplicationController
before_action :find_course, only: [:show, :edit, :update, :destroy]
def index
#academy_students = Academy::Student.all.order("created_at DESC")
# render json: Academy::Student.all
end
def new
#academy_student = Academy::Student.new
end
def show
# list = Academy::Student.find(params[:id])
# render json: list
end
def create
if #academy_student = Academy::Student.create(academy_student_params)
redirect_to #academy_student
else
render :new
end
end
def edit
end
def update
if #academy_student.update(academy_student_params)
redirect_to #academy_student
else
render :edit
end
end
def destroy
#academy_student.destroy
redirect_to #academy_student
end
private
def find_course
#academy_student = Academy::Student.find(params[:id])
end
def academy_student_params
params.require(:academy_student).permit(:student_code, :student_name, :student_gender, :student_email, :student_phone, :student_address, :student_degree, :student_grade)
end
end
routes :
namespace :academy do
resources :student
end
academy_student_index GET /academy/student(.:format) academy/student#index
POST /academy/student(.:format) academy/student#create
new_academy_student GET /academy/student/new(.:format) academy/student#new
edit_academy_student GET /academy/student/:id/edit(.:format) academy/student#edit
academy_student GET /academy/student/:id(.:format) academy/student#show
PATCH /academy/student/:id(.:format) academy/student#update
PUT /academy/student/:id(.:format) academy/student#update
DELETE /academy/student/:id(.:format) academy/student#destroy
_form.html.haml
= simple_form_for(#academy_student, html: { class: 'form-horizontal'}) do |f|
= f.error_notification
.form-inputs
= f.input :student_code, label: 'Student Code:'
= f.input :student_name, label: 'Student Name:'
= f.input :student_gender, label: 'Student Gender:'
= f.input :student_email, label: 'Student Email:'
= f.input :student_phone, label: 'Student Phone:'
= f.input :student_address, label: 'Student Address:'
= f.input :student_degree, label: 'Student Degree:'
= f.input :student_grade, label: 'Student Grade:'
= f.button :submit
Error:
NoMethodError in Academy::Student#new (when i try to run : http://localhost:3000/academy/student/new)
undefined method `academy_students_path' for #<#:0x007fd586ab8278> Did you mean? academy_student_path
academy_student_index_path
academy_student_url
academy_courses_path
Note:
This controller & model are generate without scaffold (when i use scaffold, its work)
Its working with update.

According to the naming conventions, controller name should be plural.
Which in your case is students_controller
rename student_controller.rb to students_controller.rb change your controller class name to
class Academy::StudentsController < ApplicationController
# ...
end
also, make changes in routes
routes.rb
resources :students
which will give you
academy_students GET /academy/students(.:format) academy/students#index
POST /academy/students(.:format) academy/students#create
new_academy_students GET /academy/students/new(.:format) academy/students#new
edit_academy_students GET /academy/students/:id/edit(.:format) academy/students#edit
academy_students GET /academy/students/:id(.:format) academy/students#show
PATCH /academy/students/:id(.:format) academy/students#update
PUT /academy/students/:id(.:format) academy/students#update
DELETE /academy/students/:id(.:format) academy/students#destroy

You are trying get academy/student#index
In your given routes details you should see there is no name of academy_students_path And for the academy/student#index you have academy_student_index_path.
Use academy_student_index_path instead academy_students_path

Related

Rails is rendering views very slowly

I'm still really new to Rails and working on a practice project lab and I ran into an issue where the view was rendering really slow.
Any and all help would be appreciated!
I also received this error:
SystemStackError (stack level too deep):
app/models/blogger.rb:23:in `popular_post'
app/views/bloggers/show.html.erb:13:in `_app_views_bloggers_show_html_erb__247812415140953454_70240453389320'
Gemfile
gem 'rails', '~> 5.1.6'
gem 'sqlite3'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'faker'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'capybara', '~> 2.13'
gem 'selenium-webdriver'
end
group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
My classes are Blogger, Destination, and Post (Blogger -< Post >- Destination). Below is the code for the Blogger model, show page, and controller (I didn't work on code for anything else yet, except the Blogger index but works and is just a list)
blogger.rb
class Blogger < ApplicationRecord
has_many :destinations
has_many :posts, through: :destinations
validates :name, uniqueness: true
validates :age, numericality: { greater_than: 0, message: ": You're Too Young" }
validates :bio, length: { :minimum => 30 }
def self.average_age
ages = self.all.sum do |blogger|
blogger.age
end
(ages / self.all.count)
end
def total_likes
self.posts.sum do |post|
post.likes
end
end
def popular_post
self.posts.max_by do |a|
a.likes
end
end
def top_five
self.destinations.sort_by do |destination|
destination.post_count
end.take(5)
end
end
blogger show page
<h1> <%= #blogger.name %> </h1>
<br />
<p> Age: <%= #blogger.age %> </p>
<br />
<br />
<p> Bio: <%= #blogger.bio %> </p>
<br />
<br />
<%= link_to #blogger.popular_post.title, post_path(#blogger.popular_post) %>
<br />
<%= #blogger.top_five %>
blogger controller
class BloggersController < ApplicationController
def index
#bloggers = Blogger.all
end
def show
#blogger = Blogger.find(params[:id])
end
def new
#blogger = Blogger.new
end
def create
#blogger = Blogger.create(blogger_params)
if #blogger.valid?
#blogger.save
redirect_to blogger_path(#blogger)
else
flash[:my_errors] = #blogger.errors.full_messages
redirect_to new_blogger_path
# render :new
end
end
private
def blogger_params
params.require(:blogger).permit(:name, :bio, :age)
end
end
I think that you need to modify this method
def popular_post
self.posts.max_by do |a|
a.likes
end
end
max_by is a method for an Enumerable class and you call it on a Post class, so this will not work properly. I would suggest that you use something like posts.order('likes DESC').first if likes is an Integer.
Also tiny hint you don't need to use all this self in an object and in class methods. Rails would assume that you call it on an object if this is an object method or you call it on a relation if this is a class method.
The methods total_likes, popular_post and top_five all work by assuming your associations are "arrays" (enumerations). While this works, definitally for smaller examples, it is less optimal. Because working on an array also requires the complete array to be loaded from the database first, and then do your calculations locally on a complete set (in memory). A database is optimally suited to perform such tasks (querying).
For instance, top_five can better be written to sort on the database and then only fetch the 5 first (most popular).
def top_five
destinations.order(post_count: :desc).limit(5)
end
(this is assuming that :post_count is an actual field in the database.
Similarly we can improve the other methods:
def total_likes
posts.sum(:likes)
end
just use the database: this will start a single query to return the sum of likes for all the posts of the blogger.
def popular_post
posts.order(likes: :desc).limit(1).first
end
We sort on descending likes and the select the first one. The limit 1 tells we only want to retrieve one item, but this still returns an array, so we want the first returned item.
This should improve your performance.

How to edit uploaded image with minimagick, that image is uploaded to active_storage?

I'm developing Web application, with Ruby on Rails, which is to add text to image uploaded by user. Right now I have no idea how to edit image with minimagick. What I want to ask is that how to get and edit the image which is uploaded to active_storage.
Code I wrote is here:
Gemfile
ruby '2.5.3'
gem 'rails', '~> 5.2.2'
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bootsnap', '>= 1.1.0', require: false
gem 'slim-rails'
gem 'html2slim'
gem 'carrierwave'
gem "mini_magick"
index.html.slim
.text
p Upload Image
= form_for #picture, url: {action: "create"} do |f|
= f.file_field :image
= f.submit 'Submit'
pictures_controller.rb
class PicturesController < ApplicationController
def index
#picture = Picture.new
end
def show
#picture = Picture.find_by(uuid: params[:id])
end
def create
text = 'this is test text'
image = picture_params[:image]
#picture = Picture.new(uuid: SecureRandom.uuid, image: picture_params[:image])
new_image = #picture.build_collage_image(text).tempfile.open.read
send_data new_image, :type => 'image/png', :disposition => 'inline'
end
private
def picture_params
params.require(:picture).permit(:image, :ogp)
end
end
models/picture.rb
class Picture < ApplicationRecord
include CollageMaker
include Rails.application.routes.url_helpers
after_save :build_collage_image
has_one_attached :collaged_image
has_one_attached :image
def build_collage_image(text)
CollageMaker.build(url_for(self.image), text)
end
end
concerns/collage_maker.rb
module CollageMaker
extend ActiveSupport::Concern
include Rails.application.routes.url_helpers
FONT = './app/assets/fonts/cinecaption226.ttf'.freeze
GRAVITY = 'center'
TEXT_POSITION = '0,0'
FONT_SIZE = 65
INDENTION_COUNT = 16
ROW_LIMIT = 8
def self.build(image_url, text)
text = prepare_text(text)
image = MiniMagick::Image.open(image_url)
image.combine_options do |config|
config.font FONT
config.fill 'white'
config.gravity GRAVITY
config.pointsize FONT_SIZE
config.draw "text #{TEXT_POSITION} '#{text}'"
end
end
private
def self.prepare_text(text)
text.to_s.scan(/.{1,#{INDENTION_COUNT}}/)[0...ROW_LIMIT].join("\n")
end
end
When test them, got this error.
The url_for is the view context path to the image.
To access the image internally, you need to use rails_blob_path
From the documentation...
If you need to create a link from outside of controller/view context
(Background jobs, Cronjobs, etc.), you can access the rails_blob_path
like this:
Rails.application.routes.url_helpers.rails_blob_path(user.avatar,
only_path: true)
https://edgeguides.rubyonrails.org/active_storage_overview.html

How to solve NoMethodError in RailsAdmin::Main#index?

When I try to use Rails Admin for articles. I'm getting the following error.
This Image shows you the error I am facing
Here is articles_controller.rb
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit, :update, :destroy]
before_action :authenticate_auth_user!, except: [:index, :show]
# GET /articles
# GET /articles.json
def index
#articles=Article.all
end
# GET /articles/1
# GET /articles/1.json
def show
end
# GET /articles/new
def new
#article = Article.new
end
# GET /articles/1/edit
def edit
end
# POST /articles
# POST /articles.json
def create
#article = Article.new(article_params)
respond_to do |format|
if #article.save
format.html { redirect_to #article, notice: 'Article was successfully created.' }
format.json { render :show, status: :created, location: #article }
else
format.html { render :new }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /articles/1
# PATCH/PUT /articles/1.json
def update
respond_to do |format|
if #article.update(article_params)
format.html { redirect_to #article, notice: 'Article was successfully updated.' }
format.json { render :show, status: :ok, location: #article }
else
format.html { render :edit }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
# DELETE /articles/1
# DELETE /articles/1.json
def destroy
#article.destroy
respond_to do |format|
format.html { redirect_to articles_url, notice: 'Article was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_article
#article = Article.find(params[:id])
#comments = #article.comments.all
#comment = #article.comments.build
end
# Never trust parameters from the scary internet, only allow the white list through.
def article_params
params.require(:article).permit(:title, :meta_description, :description, :category_id, :video)
end
end
And here is article.rb file in model
class Article
include Mongoid::Document
include Mongoid::Timestamps
has_many :comments
belongs_to :category
field :title, type: String
field :meta_description, type: String
field :description, type: String
field :category_id, type: String
field :video, type: String
end
Here is my gemfile
source 'https://rubygems.org'
ruby "2.3.1"
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0.6'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
gem 'mongoid', '~>6.0.3'
gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'
gem 'friendly_id', '~> 5.2'
gem 'devise', '~> 4.2'
gem 'mail_form', '~> 1.6'
gem 'ckeditor', '~> 4.2'
gem 'rails_admin', '~> 1.1'
gem 'twitter-bootstrap-rails', '~> 3.2', '>= 3.2.2'
gem 'bootstrap-sass', '3.2.0.2'
gem 'less-rails', '~> 2.8'
gem 'therubyracer', '~> 0.12.2'
gem 'mongoid-ancestry', '~> 0.4.2'
gem 'simple_form', '~> 3.3', '>= 3.3.1'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :production do
gem 'pg', '~> 0.19.0'
gem 'rails_12factor', '~> 0.0.3'
end
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platform: :mri
end
group :development do
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
gem 'web-console'
gem 'listen', '~> 3.0.5'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
comment.rb
class Comment
include Mongoid::Document
include Mongoid::Timestamps
belongs_to :article
field :name, type: String
field :email, type: String
field :article_id, type: String
field :comment, type: String
end
category.rb
class Category
include Mongoid::Document
include Mongoid::Ancestry
has_many :articles
has_ancestry
mount_uploader :image, FileUploader
field :name, type: String
field :image, type: String
field :parent_id, type: String
end
How can I solve this problem?

Will_Paginate NoMethodError (undefined method `paginate'

I'm trying to in the "will_paginate" gem however when I push it to Heroku, I get the following error message on the Heroku server. The solution works perfectly in my development in environment.
2015-11-06T18:34:43.422821+00:00 app[web.1]: Processing by AccountsController#index as HTML
2015-11-06T18:34:43.509289+00:00 app[web.1]:
2015-11-06T18:34:43.509292+00:00 app[web.1]: NoMethodError (undefined method `paginate' for #<Account::ActiveRecord_Relation:0x007f39bc853bd8>):
2015-11-06T18:34:43.509293+00:00 app[web.1]: app/controllers/accounts_controller.rb:8:in `index'
2015-11-06T18:34:43.509294+00:00 app[web.1]:
2015-11-06T18:34:43.509295+00:00 app[web.1]:
Accounts Controller:
class AccountsController < ApplicationController
before_action :authenticate_user!
before_action :set_account, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#account = Account.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 8)
end
def show
#notes = Note.where(account_id: #account.id) #Where a note belong to the current account
end
def new
#account = Account.new
respond_with(#account)
end
def edit
end
def create
#account = Account.new(account_params)
#account.save
respond_with(#account)
end
def update
#account.update(account_params)
respond_with(#account)
end
def destroy
#account.destroy
respond_with(#account)
end
private
def set_account
#account = Account.find(params[:id])
end
def account_params
params.require(:account).permit(:first_name, :last_name, :return_client, :program_id, :insurance_id, :address, :phone)
end
end
Index.html.erb
<br>
<%= will_paginate #account , renderer: BootstrapPagination::Rails %>
<br>
<%= link_to 'Add Client', new_account_path %>
Gem File
source 'http://rubygems.org'
ruby '2.1.5'
gem 'rails', '4.1.8'
gem 'sqlite3', group: :development
gem 'sass-rails', '~> 4.0.3'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'rails_12factor', group: :production
gem 'pg', group: :production
gem 'carrierwave'
gem "fog"
gem "figaro"
gem 'tzinfo-data', platforms: [:mingw, :mswin]
gem 'execjs'
gem "mini_magick"
gem 'devise'
gem 'searchkick'
group :development, :test do
gem 'rspec-rails', '~> 3.0'
gem 'will_paginate', '~> 3.0'
gem 'will_paginate-bootstrap'
end
Then gem env is the same on both servers. I'm not sure what the problem is.
Remove gem 'will_paginate', '~> 3.0' from group :development, :test do to gem 'will_paginate', '~> 3.0', group: :production and that corrected the NoMethodError message in the Heroku log.

Form inputs don't create record

I am using paperclip and dropbox for images.
I am not sure why I am getting this. Some of the solutions i tried for resolving the sqlite3 busy exception error didn't work.
But I also suspect my parameters somehow aren't correct...
the controller specifies i need a character object, but the parameters don't seem to have that. I know i use a file attachment called :image, but paperclip, imagemagick, and dropbox are supposed to handle the creation of the image attributes once the image gets uploaded and the form is submitted.
This is the error I get in my browser.
Form:
= form_for(#character, :html => { :multipart => true }) do |f|
- if #character.errors.any?
#error_explanation
%h2= "#{pluralize(#character.errors.count, "error")} prohibited this character from being saved:"
%ul
- #character.errors.full_messages.each do |msg|
%li= msg
#stripe_error.alert.alert-danger{ :style => "display:none" }
%noscript JavaScript is not enabled and is required for this form. First enable it in your web browser settings.
.form-group
= f.label :name
= f.text_field :name
.form-group
= f.label :image
= f.file_field :image
.action
= f.submit
Controller:
def create
#character = Character.new(character_params)
respond_to do |format|
if #character.save
format.html { redirect_to #character, notice: 'Character was successfully created.' }
format.json { render action: 'show', status: :created, location: #character }
else
format.html { render action: 'new' }
format.json { render json: #character.errors, status: :unprocessable_entity }
end
end
end
...
private
# Use callbacks to share common setup or constraints between actions.
def set_character
#character = Character.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def character_params
params.require(:character).permit(:name, :image)
end
end
Gemfile: (yes, did bundle install)
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more:
https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
# Use Haml for views
gem 'haml-rails'
gem 'bootstrap-sass', "~> 3.0.3.0"
gem 'paperclip', "~> 3.0"
gem 'paperclip-dropbox', ">= 1.1.7"
group :development do
gem 'nokogiri'
#gem 'hpricot', '0.8.6'
gem 'ruby_parser', '~> 3.1.1'
# erubis is already included in action pack
gem 'html2haml'
end
group :development, :test do
gem 'sqlite3'
end
group :production do
gem 'pg'
gem 'rails_12factor'
end
# Use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'
# Use unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano', group: :development
# Use debugger
# gem 'debugger', group: [:development, :test]

Resources