Reputation: 435
I'm creating a blog where articles can be responses to other articles. Articles can also be part of groups. However articles do not have to be in a group or be a response to another article.
I'm attempting to follow the Rails docs to create articles as self-joined records.
I created user, group and article scaffolds:
bin/rails g scaffold user username:string email:string birthday:date
bin/rails g scaffold group name:string user:references
bin/rails g scaffold article user:references parent:references title:string subheading:string body:text pub_date:datetime group:references hidden:boolean prompt:boolean
I'm trying to use allow_nil
in the model validation.
class Article < ApplicationRecord
belongs_to :user
belongs_to :parent, class_name: "Article"
has_many :replies, class_name: "Article", foreign_key: "parent_id"
belongs_to :group
validates :parent, length: {minimum: 1}, allow_nil: true
validates :group, length: {minimum: 1}, allow_nil: true
end
However when I run the db:seed:
user1 = User.create(username: "pete01",email: "[email protected]",
birthday:"1980-01-30")
article1 = Article.create!(user:user1, parent:nil, title:"My First Article",
subheading:"This is important", body:"The body of my first article",
pub_date:"2015-12-26", group:nil, hidden:false, prompt:false)
I get this error:
ActiveRecord::RecordInvalid: Validation failed: Parent must exist, Group must exist
Is there somewhere else where I should be telling Rails it does not need to validate Group and Parent?
Upvotes: 2
Views: 9635
Reputation: 16394
This is most likely to be the result of migrating to Rails 5, where the default for belongs_to
relations changed. See this answer for details,
Upvotes: 2
Reputation: 111
Solution is to find the file new_framework_defaults.rb
, change this to false
:
Rails.application.config.active_record.belongs_to_required_by_default = false
Upvotes: 7
Reputation: 76784
#app/models/article.rb
class Article < ActiveRecord::Base
belongs_to :parent, class_name: "Article"
belongs_to :group
validates :parent, presence: true, allow_nil: true
validates :group, presence: true, allow_nil: true
end
Several problems for you:
You're validating parent
& group
-- these are associative objects.
Your error says "[Object] must exist"
, which means your validation works -- Rails cannot find a "nil" association (it's expecting objects).
What you should have is either to validate parent_id
& group_id
, or to validate the presence of the associative object with something like presence
.
I've included the following validations I would use:
validates :parent, presence: true, allow_nil: true
validates :group, presence: true, allow_nil: true
You could also try:
validates :parent_id, length: { minimum: 1 }, allow_nil: true
validates :group_id, length: { minimum: 1 }, allow_nil: true
Articles can also be part of groups
You'll probably want to use a has_and_belongs_to_many
association for it then:
#app/models/article.rb
class Article < ActiveRecord::Base
has_and_belongs_to_many :groups
end
#app/models/group.rb
class Group < ActiveRecord::Base
has_and_belongs_to_many :articles
end
You'll need a join table called articles_groups
with the columns article_id
& group_id
:
You can create the migration as follows:
$ rails g migration CreateArticlesGroups
# db/migrate/create_articles_groups__________.rb
class CreateArticlesGroups < ActiveRecord::Migration
def change
create_table :articles_groups, id: false do |t|
t.belongs_to :article, index: true
t.belongs_to :group, index: true
end
end
end
$ rake db:migrate
This will allow you to populate the associative objects like this:
@article = Article.find params[:article_id]
@group = Group.find params[:id]
@article.groups << group
Upvotes: 3
Reputation: 2669
allow_nil: true
is an option to a validator, not to the validates
method. You are using the length:
key which will call the LengthValidator
with the {minimum: 1}
hash as arguments (similar to using validates_length_of
).
E.g., use
validates :parent, length: {minimum: 1, allow_nil: true}
instead of
validates :parent, length: {minimum: 1}, allow_nil: true
Note: If using multiple validators, you will need to specify allow_nil
for each of them.
Upvotes: 1
Reputation: 1545
Try to remove your validations. Also check your migration for Article
. Maybe you have null: false
there for group_id
and parent_id
class Article < ApplicationRecord
belongs_to :user
belongs_to :parent, class_name: "Article"
has_many :replies, class_name: "Article", foreign_key: "parent_id"
belongs_to :group
end
Upvotes: 0