Devise undefined method `build' for nil:NilClass - ruby-on-rails

I am currently enrolled in a online course in ruby on rails and im learning everything from scratch so pardon me if Im not clear in my questions. Here is my delima, I am trying to create a LINK between two Models in the rails application and here is what I have so far. However when I try to access localhost3000/business/new it returns the error mentioned it the title. I have come to the conclusion that it is because of me using a "has_one :model" type of association, rather than the "has_many :model". I hope someone can point me in the right direction here as I have spent hours searching to no solutions.
class BusinessesController < ApplicationController
before_action :set_business, only: [:show, :edit, :update, :destroy]
//edited for clarity
def new
#business = current_user.business.build //The line that returns a undefined method for nil class
end
def edit
end
def create
#business = current_user.business.build(business_params)
if #business.save
redirect_to #business, notice: 'Business was successfully created.'
else
render "new"
end
end
Devise User Model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :buzzs, dependent: :destroy
has_one :business, dependent: :destroy
end
Business Model
class Business < ActiveRecord::Base
belongs_to :user
end

Take a look at this http://guides.rubyonrails.org/association_basics.html#has-one-association-reference.
You should use build_business instead of business.build
4.2.1 Methods Added by has_one
When you declare a has_one association, the declaring class automatically gains five methods related to the association:
association(force_reload = false)
association=(associate)
build_association(attributes = {})
create_association(attributes = {})
create_association!(attributes = {})

One to One Association:
class User < ActiveRecord::Base
has_one :business
end
current_user.build_business
Or if One to Many:
class User < ActiveRecord::Base
has_many :businesses
end
current_user.businesses.build

Related

undefined method `before_action' for Profile:Class

Good afternoon, beautiful community, I have the following query: I have this error even though the method is well defined, if someone can give me a hand.
I want when a user registers to automatically create a profile for said user
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :patients, dependent: :destroy
has_one :profile, dependent: :destroy
after_create :set_profile
def set_profile
self.profile = Profile.create()
end
end
class Profile < ApplicationRecord
before_action :set_profile
belongs_to :user
private
def set_profile
#profile = (current_user.profile ||= Profile.create)
end
end
class ProfilesController < ApplicationController
before_action :set_profile
def show
end
def edit
end
def update
end
private
def set_profile
#profile = (current_user.profile ||= Profile.create)
end
end
The error occurs because you're mixing up the model callbacks and the before_action that belongs in the controller in your Profile class. It should not be before_action but before_save or something like that.
See a list of available callbacks for the models here: https://guides.rubyonrails.org/active_record_callbacks.html#available-callbacks
If you're goal is to just create a profile after creating a user the code in your User class is sufficient. No need to add another callback in the Profile class (but of course you can if you want to deal with other stuff there).

voting system for rails blog with devise user login before voting

So I have a blog I am trying to have a simple upvote/downvote feature for the posts. I have devise set up and I made all the associations between the models, votings, users, and home_blogs.
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :liked_home_blogs, through: :votings
end
class HomeBlog < ApplicationRecord
mount_uploader :image, ImageUploader
has_many :hashtaggings
has_many :hashtags, through: :hashtaggings
has_many :votings
has_many :votants, through: :votings
def all_hashes=(names)
self.hashtags = names.split(",").map do |name|
Hashtag.where(name: name.strip).first_or_create!
end
end
def all_hashes
self.hashtags.map(&:name).join(", ")
end
end
class Voting < ApplicationRecord
belongs_to :home_blog
belongs_to :user
end
and the controller looks like this at the moment:
class VotingsController < ApplicationController
before_action :authenticate_user!
def upvote
#votings = HomeBlog.find(params[:home_blog_id])
#votings.votings.build( :upvote => true, :downvote => false,
:user_id => current_user.id)
#votings.save!
redirect_to request.referrer, notice: "Thanks for the
vote!"
end
def downvote
#voting = HomeBlog.find(params[:home_blog_id])
#voting.votings.build( :downvote => true, :upvote =>
false, :user_id => current_user.id)
#voting.save!
redirect_to request.referrer, notice: "Thanks for the
vote!"
end
private
def voting_params
params.require(:voting).permit(:upvote, :downvote,
:home_blog_id, :user_id)
end
end
Sorry about the crappy copy and paste for the controller. My question is, how do I make a condition for the current_user in devise to limit them to one vote per home_blog post? Thanks!
I think you would add multicolumn unique index to the join table. Something like...
add_index :voting, [:user_id, :home_blog_id], unique: true
If im understanding your question correctly you would like there to be only one votings record for a home_blog per current_user ( user_id )

NameError uninitialized constant Model::Object

I'm new to ruby on rails. Ihe error I have is
NameError in ReviewsController#create
uninitialized constant User::Review
Extracted source:
#review = current_user.reviews.build(review_params)
I read on other stack overflow questions that usually the error for wrong names or forgetting belongs_to or has_many but I believe I've set the relations correctly. I am using the gem devise to handle the user and sign in/sign up etc
Reviews.rb
class Reviews < ActiveRecord::Base
belongs_to :user
belongs_to :renters
end
User.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :reviews
end
Reviews_Controller.rb
class ReviewsController < ApplicationController
before_action :set_renter
before_action :authenticate_user!
def new
#review = Reviews.new(renters: #renter)
end
def create
#review = current_user.reviews.build(review_params)
#review.renter = #renter
#review.save
redirect_to #renter
end
private
def set_renter
#renter = Renters.find(params[:renter_id])
end
def review_params
params.require(:reviews).permit(:comment, :rating)
end
end
The Renters model is working fine and similar code I have to make a new Renter is working so I am not sure what is wrong.
ActiveRecord::Base classes are usually named in singular.
That means your class should be named Review and it should be stored in a file named models/review.rb (but still store its entries in a reviews database table).
If you do not want to follow this convention than you have to explicitly tell Rails that the class is named differently in the definition of the belongs_to and has_many association.
your model class for your reviews table should be Review in the file: app/models/review.rb
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :renters
end
and your User model representing users table should be in the file: app/models/user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :reviews
end
NOTE: for this association to work, your reviews table must have a column user_id as the foreign key for performing activerecord operations on associated models (for example: User.find(1).reviews to get all records of reviews table whose user_id is 1)
This occours by convention of Rails. You can force with function class_name the class Reviews
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :reviews, class_name: "Reviews"
end

Rails has_many through

A user can create organization and then he can make other users as moderators to his organization. Below method shows how the organization is created.
def create
#organization = current_user.organizations.build(organization_params)
# Confirm organization is valid and save or return error
if #organization.save!
# New organization is saved
respond_with(#organization) do |format|
format.json { render :json => #organization.as_json }
end
else
render 'new', notice: "Unable to create new organization."
end
end
How should I create moderators for the organization. I tried using has_many through but it failed. Can somebody help me?
Update
Organization Model
class Organization < ActiveRecord::Base
has_many :moderators
has_many :users, :through => :moderators
end
UserModel
class User < ActiveRecord::Base
enum role: [:user, :moderator, :organization, :admin]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :user
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :moderators
has_many :organizations, :through => :moderators
end
Moderator Model
class Moderator < ActiveRecord::Base
belongs_to :user
belongs_to :organization
end
When I create new organization my organization user_id is nil?
Take look at has and belongs to many relation http://apidock.com/rails/v4.2.1/ActiveRecord/Associations/ClassMethods/has_and_belongs_to_many since one user can be moderator for many organization and organization can have many moderators. Also instead of calling #organization.save! you should call #organization.save because now it will throw error if save would be unsuccessful. You want to have boolean as result of save so your condition works properly

Can't create user, "undefined method `save' for nil:NilClass" using Devise in Rails 4

When trying to create a new Person I receive the following error on the line if #persons.save:
NoMethodError in PeopleController#create,
undefined method `save' for nil:NilClass
Any thoughts on how to fix would be much appreciated, thanks.
Controller
# GET /people/new
def new
#person = current_user.person.build
end
# GET /people/1/edit
def edit
end
# POST /people
# POST /people.json
def create
#person = current_user.person.build(person_params)
respond_to do |format|
if #person.save
format.html { redirect_to #person, notice: 'Person was successfully created.' }
format.json { render action: 'show', status: :created, location: #person }
else
format.html { render action: 'new' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
User model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :person
end
Person model
class Person < ActiveRecord::Base
has_many :user
has_paper_trail
acts_as_taggable
#tags = Person.acts_as_taggable_on :tags
def admin_permalink
admin_post_path(self)
end
end
It seems like you want a relationship where a user can have many people and a person can have many users.
This requires a special association type called has_many through.
Basically a user can be associated to many people and vice versa, :through a third model called a join table.
e.g
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :people, through: :relationships # The model name(person) is pluralised for has_many associations
end
class Person < ActiveRecord::Base
has_many :users, through: :relationships # user needs to be pluralised here
has_paper_trail
acts_as_taggable
#tags = Person.acts_as_taggable_on :tags
...
end
class Relationship < ActiveRecord::Base # This is the join table
belongs_to :user
belongs_to :person
end
This requires you to create the relationship table in the database (Instead of relationship, call it whatever makes the most sense). It needs person_id and user_id integer columns.
In your controller you will then need to use the pluralised version too:
#person = current_user.people.build(person_params)
You should have a good read of the rails association guide. Particularly the has_many through section.
There is another type of association called a has_and_belongs_to_many which may be better for your case. In my experience it often seems like the easier approach but ends up causing headaches compared to has_many through.

Resources