Fliendly_ID - URL not being displayed - ruby-on-rails-4

I am new to ROR and working on a small project. Recently I added the friendly ID gems and followed the instruction on the documentation. But I can't seem to get the URL working. I added the friendly id to communities model which is basically your posts model.
Route code:
class Community < ActiveRecord::Base
extend FriendlyId
friendly_id :title, use: [:slugged, :history]
validates :title, :length => { :minimum => 5 }
has_attached_file :post_image, :styles =>
{ :medium => "300x300>", :thumb => "100x100>", :large => "1280x720", :headline => "1280x720"}
validates_attachment_content_type :post_image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
belongs_to :member
has_many :comments
scope :newest_first, lambda { order("communities.created_at DESC")}
scope :without_community, lambda{|community| community ? {:conditions => ["community.id != ?", #community.id]} : {} }
# def to_param
# "#{id}-#{title.parameterize}"
# end
end
I even tried the to_param to get the URL's. But nothing seems to work.
Controller code:
class CommunitiesController < ApplicationController
before_action :set_community, only: [:show, :edit, :update, :destroy]
layout "community"
before_filter :authenticate_member!, except: [:index, :show]
require 'will_paginate/array'
# GET /communities
# GET /communities.json
def index
#communities = Community.newest_first.friendly.where(params[:id]).paginate(page: params[:page], per_page: 9)
end
# GET /communities/1
# GET /communities/1.json
def show
#communities = Community.newest_first.friendly.where(params[:title]).paginate(page: params[:page], per_page: 5).where('id NOT IN (?)', #community.id)
end
# GET /communities/new
def new
#community = Community.new({:member_id => current_member.id})
end
# GET /communities/1/edit
def edit
end
# POST /communities
# POST /communities.json
def create
#community = Community.new(community_params)
respond_to do |format|
if #community.save
format.html { redirect_to #community, notice: 'Post: #{#community.title.capitalize} was successfully created.' }
format.json { render :show, status: :created, location: #community }
else
format.html { render :new }
format.json { render json: #community.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /communities/1
# PATCH/PUT /communities/1.json
def update
respond_to do |format|
if #community.update(community_params)
format.html { redirect_to #community, notice: 'Post: #{#community.title.capitalize} was successfully updated.' }
format.json { render :show, status: :ok, location: #community }
else
format.html { render :edit }
format.json { render json: #community.errors, status: :unprocessable_entity }
end
end
end
# DELETE /communities/1
# DELETE /communities/1.json
def destroy
#community.destroy
respond_to do |format|
format.html { redirect_to communities_url, notice: 'Post: #{#community.title.capitalize} was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_community
#community = Community.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def community_params
params.require(:community).permit(:name,:post_image, :title, :content, :member_id)
end
end
But If I type the URL like http://localhost:3000/communities/post.title I am able to go directly to the post. That means the slugs have been created and they are working kind of. But I can't seem to get them displayed on the URL.
I have tried many permutation and combinations but nothing seems to work.
Would really appreciate any help. Let me know if there is any other specific code you require.
FYI: Migrations code:
class AddSlugToCommunities < ActiveRecord::Migration
def change
add_column :communities, :slug, :string, limit: 191
add_index :communities, :slug, unique: true
end
end
Friendly_ID migration code:
class CreateFriendlyIdSlugs < ActiveRecord::Migration
def change
create_table :friendly_id_slugs do |t|
t.string :slug, :null => false, limit: 191
t.integer :sluggable_id, :null => false
t.string :sluggable_type, :limit => 50
t.string :scope, limit: 191
t.datetime :created_at
end
add_index :friendly_id_slugs, :sluggable_id
add_index :friendly_id_slugs, [:slug, :sluggable_type]
add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], :unique => true
add_index :friendly_id_slugs, :sluggable_type
end
end

Went deeper into the code and found that slugs were being made. its just that the URL was not being linked properly. Made a few changes to the links to to use slugs instead of :id to get it working.
Thanks anyways #uzaif

Related

Getting an error message on Michael Hartl's Ruby on Rails Tutorial: NoMethodError in MicropostsController#create, how do I avoid getting this message?

Can't add or edit a new micropost in my toy_app (Chapter 2 of the Rails Tutorial). Before I added users and microposts with no problem. Then I specified the has_many / belongs_to relationship and ever since I'm getting:
"NoMethodError in MicropostsController#create undefined method `content' for
Did you mean? context context= context?" when I try to create and microposts, and a similar message when updating a micropost.
It might be worth nothing that I only had one user, and the user id was "3"... not sure why it wouldn't be 1. I've since deleted all microposts and still only have 1 user. How do I avoid this error message? If anyone could help I would greatly appreciate it.
The Microposts Controller:
class MicropostsController < ApplicationController
before_action :set_micropost, only: [:show, :edit, :update, :destroy]
# GET /microposts
# GET /microposts.json
def index
#microposts = Micropost.all
end
# GET /microposts/1
# GET /microposts/1.json
def show
end
# GET /microposts/new
def new
#micropost = Micropost.new
end
# GET /microposts/1/edit
def edit
end
# POST /microposts
# POST /microposts.json
def create
#micropost = Micropost.new(micropost_params)
respond_to do |format|
if #micropost.save
format.html { redirect_to #micropost, notice: 'Micropost was successfully created.' }
format.json { render :show, status: :created, location: #micropost }
else
format.html { render :new }
format.json { render json: #micropost.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /microposts/1
# PATCH/PUT /microposts/1.json
def update
respond_to do |format|
if #micropost.update(micropost_params)
format.html { redirect_to #micropost, notice: 'Micropost was successfully updated.' }
format.json { render :show, status: :ok, location: #micropost }
else
format.html { render :edit }
format.json { render json: #micropost.errors, status: :unprocessable_entity }
end
end
end
# DELETE /microposts/1
# DELETE /microposts/1.json
def destroy
#micropost.destroy
respond_to do |format|
format.html { redirect_to microposts_url, notice: 'Micropost was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_micropost
#micropost = Micropost.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def micropost_params
params.require(:micropost).permit(:context, :user_id)
end
end
Microposts model:
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length: { maximum: 140 }
end
Users model:
class User < ApplicationRecord
has_many :microposts
end
Users Controller
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, :email)
end
end
schema.rb:
ActiveRecord::Schema.define(version: 20171222133429) do
create_table "microposts", force: :cascade do |t|
t.text "content"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
In your micropost_params you have permitted context. I assume it should be a content. Please check your schema.rb to verify what columns does your microposts table have.

uploading image or file in ruby on rails 4

Here, I want a clear concept about uploading file or image without using any gemfile(Ex: peperclip, carrierwave etc).
Previously, I did some work. Where i can upload images in "/assets/images" folder. But i could't see images when i call it in my show page(there was only a placeholder of break image).
here is the screenshot of show page:
how can i show those images in my show.html.erb file?
Here is my ImagesController.rb file:
class ImagesController < ApplicationController
before_action :set_image, only: [:show, :edit, :update, :destroy]
# GET /images
def index
#images = Image.all
end
# GET /images/1
def show
end
# GET /images/new
def new
#image = Image.new
end
# GET /images/1/edit
def edit
end
# POST /images
def create
#image = Image.new(image_params)
if params[:image].present?
file = params[:image][:picture]
File.open(Rails.root.join('app','assets', 'images', file.original_filename), 'wb') do |f|
f.write(file.read)
end
end
respond_to do |format|
if #image.save
format.html { redirect_to #image, notice: 'Image was successfully created.' }
format.json { render action: 'show', status: :created, location: #image }
else
format.html { render action: 'new' }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #image.update(image_params)
format.html { redirect_to #image, notice: 'Image was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
# DELETE /images/1
def destroy
#image.destroy
respond_to do |format|
format.html { redirect_to images_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_image
#image = Image.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def image_params
params.require(:image).permit(:name)
end
end
Here is my show.html.erb file:
<p><%= #image.name %></p>
<p><%= image_tag #image.picture %></p>
Here is my schema.rb file:
ActiveRecord::Schema.define(version: 20140725043842) do
create_table "images", force: true do |t|
t.string "name"
t.string "picture"
t.datetime "created_at"
t.datetime "updated_at"
end
end
please tell me, if you need more information about my project.
please give me some advice. I want a clear understand about uploading image/file and show them without using gemfile.
You have to upload images to a folder that doesn't need precompiling to be show, as assets do. Try uploading them to public folder.
Also you might want to read about the asset pipeline and why aren't they displaying:
http://guides.rubyonrails.org/asset_pipeline.html

ActiveModel::ForbiddenAttributesError - Rails4

Environment:
Windows 8.1
Rails4
Ruby 2
I am using Devise and I have two separate controllers: users_controller.rb and registrations_controller.rb.
Following is my registrations_controller.rb:
class RegistrationsController < Devise::RegistrationsController
before_filter :update_sanitized_params, if: :devise_controller?
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:first, :last,
:email, :password,
:password_conf, :password_changed_at)}
devise_parameter_sanitizer.for(:account_update) {|u| u.permit(:first, :last, :salutation,
:email, :password,
:password_conf, :password_changed_at, :current_passwor)}
end
# GET /registrations/new
def new
super
end
# POST /registrations
# POST /registrations.json
def create
#user = User.new(registration_params)
#user.email = #user.email.downcase
##user.slug = "#{#user.first.downcase}_#{#user.last.downcase}_#{#user.email}"
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: t('registration_successfully_created') }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /registrations/1
# DELETE /registrations/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to registrations_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_registration
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def registration_params
params[:user]
end
end
and following is my User model: user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:password_expirable, :confirmable, :lockable, :timeoutable
validates :first, presence: true
validates :last, presence: true
validates :email, :email => true, presence: true, uniqueness: {case_sensitive: false}
before_save { |user| user.email = email.downcase }
end
When I try to create a new user, I get an error message:
ActiveModel::ForbiddenAttributesError
The following line is highlighted in the registrations controller:
#user = User.new(registration_params)
Witht the additional debug information:
{"utf8"=>"✓", "authenticity_token"=>"CRwY4emBZJXhH7kMNGQZR5H1D3D0IJrHCnBzs5PTE8U=", "user"=>{"email"=>"xxxx#jkjjjkj.com", "password"=>"xxxxxxx", "password_confirmation"=>"xxxxxxx", "first"=>"John", "last"=>"Doe"}, "commit"=>"Create User", "action"=>"create", "controller"=>"registrations"}
Any ideas?
You have defined a method for strong parameters but you cannot just return the params hash - instead you have to specifically whitelist the attributes you wish to pass on to the model.
def registration_params
params.require(:user).permit(:email, :password, :password_confirmation, ...) # etc for the rest of your attributes
end

NoMethodError in Courses#edit undefined method `model_name'

I need help with the follow problem. I have been looking at similar questions but am still unable to find the solution to the problem. I am currently having this problem.
NoMethodError in Courses#edit
undefined method `model_name' for #Class:0xb5068474
the error seems to be with this line of code.
<%= simple_fields_for #lesson do |f| %>
<%= f.input :lesson_name %>
<%end%>
The lesson database is link to the course database, where course has_many lessons and lesson belongs_to course. I think that the problem may be due to my controller code. I am relatively new and not very sure about how to go about solving this problem.
I am able to go to create page to create that relation but nothing else is saved inside the database but the id of course and lesson. However, when i go to the edit page for course, this error pops out.
courses_controller.rb
class CoursesController < ApplicationController
before_action :set_course, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, :except => [:show,:index]
# GET /courses
# GET /courses.json
def index
#courses = Course.all
end
# GET /courses/1
# GET /courses/1.json
def show
end
# GET /courses/new
def new
#course = Course.new
#lesson = #course.lessons.build
end
# GET /courses/1/edit
def edit
#course = Course.find(params[:id])
#lesson = #course.lessons
end
# POST /courses
# POST /courses.json
def create
#course = Course.new(course_params)
#course.lessons.new(lesson_params)
respond_to do |format|
if #course.save
format.html { redirect_to #course, notice: 'Course was successfully created.' }
format.json { render action: 'show', status: :created, location: #course }
else
format.html { render action: 'new' }
format.json { render json: #course.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /courses/1
# PATCH/PUT /courses/1.json
def update
respond_to do |format|
if #course.update(course_params)
#course.lesson.update_attributes(lesson_params)
#course.staff_ids=params[:course][:staff_ids]
format.html { redirect_to #course, notice: 'Course was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #course.errors, status: :unprocessable_entity }
end
end
end
# DELETE /courses/1
# DELETE /courses/1.json
def destroy
#course.destroy
respond_to do |format|
format.html { redirect_to courses_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_course
#course = Course.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def course_params
params.require(:course).permit(:course_code, :course_name, :year_of_study, :discipline, :Acad_unit, :cohort_size, :remark)
end
def lesson_params
params.require(:lesson).permit(:lesson_type, :lesson_name, :num_lesson, :frequency)
end
end
lesson.rb
class Lesson < ActiveRecord::Base
belongs_to :course
end
course.rb
class Course < ActiveRecord::Base
validates_presence_of :course_code, :course_name
validates_uniqueness_of :course_code, :course_name
validates :year_of_study, :Acad_unit, :cohort_size, :numericality => { :greater_than => 0}
has_and_belongs_to_many :staffs, join_table: :scheduleCourse
has_many :lessons, dependent: :destroy
end
Please give me some advise. Thanks in advance
The error that you get:
undefined method `model_name` for #Class:0xb5068474
Means that simple_fields_for method is doing something like #lesson.class.model_name, which is ok when object you pass (#lesson) is an instance of ActiveRecord::Base, but in edit action you define #lesson
#lesson = #course.lessons
As a relation, so it is not one Lesson instance, it is internal ActiveRecord object for storing relations. If for instance you call first on it:
#lesson = #course.lessons.first
This should work. Or you can iterate through collection of lessons in view to create form for each one of them, it depends on what you want to do.

Rails 4 has_secure_password

In a Rails 4 app -- I am getting this error when trying to create a simple User in my console.
RuntimeError:
Password digest missing on new record
My model, controller, and schema looks like:
class User < ActiveRecord::Base # User.rb
has_secure_password
end
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to root_path, notice: "Thank you for signing up!"
else
render "new"
end
end
private
def user_params
params.require(:user).permit(:email, :name, :password, :password_confirmation)
end
end
create_table "users", force: true do |t| #db/schema.rb (edited for brevity)
t.string "email"
t.string "name"
t.text "password_digest"
t.datetime "created_at"
t.datetime "updated_at"
end
I am using postgresql, and am not sure if this is a bug, or if I have missed something simple.
Thanks,
In Rails 4 all of the attributes are mass assigned by default so you don't need to use attr_accesible. Now you have to state which ones you want to protect. you would write it like this
attr_protected :admin
The error that you are getting gets raised when password_digest is blank. It probably has something to do with your attr_accesor:. Can I see your view?
I had exact the same problem but that part here solved my problem. The password_confirmation could not be stored because it was not a permit parameter
def user_params
params.require(:user).permit(:name, :password_digest, :password, :password_confirmation)
end
I did it in rails 4:
for use "has_secure_password" you have to use the parameter password_digest
Schema Information = name :string, password_digest :string
class User < ActiveRecord::Base
has_secure_password
validates :name, presence: true, uniqueness: true
validates_presence_of :password, :on => :create
end
and the controller
def user_params
params.require(:user).permit(:name, :password_digest,
:password, :password_confirmation)
end
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to users_url, notice: "User #{#user.name} was successfully created.'"}
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end