I have two models like so:
class Kid < ActiveRecord::Base
belongs_to :sex
attr_accessible :name
end
class Sex < ActiveRecord::Base
attr_accessible :description
has_many :kids
end
But for the life of me, I cannot figure out how to get the association to show up in the admin. When I go to edit a kid, I see a label for sex, but there is no dropdown, no hint whatsoever that RailsAdmin sees the association. It just shows the label name, a blank space and the word "optional" below.
I've searched through the dox over and over and over, yet I can't find a solution. I'm a noob, so it's possible I looked right over it and should be subject to ridicule.
I have not modified any other admin code.
The relation should be accessible in Kid, try to add sex_id to accessible attributes.
class Kid < ActiveRecord::Base
belongs_to :sex
attr_accessible :name, :sex_id
end
Thanks to Gaƫl Marziou, I figured out how to 'connect' with the intermediate model (the one used with has_many :through... association) like so:
class CategoryPets < ActiveRecord::Base
belongs_to :category
belongs_to :pet
attr_accessible :category_id, :pet_id
end
Related
Is it a bad practice to set a model (table) association between both parent and child AND grandparent and child? For example, if I want to easily query a user's projects or a user's tasks, is the following setup recommended? If so, is there a good way to ensure both foreign keys always point to the same user?
Any help will be greatly appreciated.
class User < ActiveRecord::Base
attr_accessible :email, :first_name, :last_name
has_many :projects
has_many :tasks
end
class Project < ActiveRecord::Base
attr_accessible :name, :status
belongs_to :user
has_many :tasks
end
class Task < ActiveRecord::Base
attr_accessible :name, :status
belongs_to :user
belongs_to :project
end
There is nothing wrong with what you are trying to do, in fact rails has already predefined some association methods to help you. Just a couple of modifications and you are good to go
class User < ActiveRecord::Base
attr_accessible :email, :first_name, :last_name
has_many :projects
has_many :tasks, through: :projects
end
By adding the through: :projects to your tasks now means you can access all of a users tasks like so
$user = User.first #or whatever
$user.tasks
=> [AR array of all tasks]
You can play around with it in irb. In addition you don't need belongs_to :user in your Task model. It's already taken care of.
Look at section 2.4 for more details
EDIT: I have made the assumption (based upon your description) that a task belongs to a project, and a project belongs_to a user, and that user's don't have tasks directly, but through projects. If that was wrong, let me know and we'll figure it out from there.
I have one project for school and I am little bit confused how to make tag and category asociated posts so when I was looking for some tips in google I found this thread. So I tried scaffolding as described and it was working just fine, but when I ran the server and tried to create new post this appeared:
ActiveModel::MassAssignmentSecurity::Error in PostsController#create
Can't mass-assign protected attributes: category, user
So I really don't know what is wrong but I can use some help. Or maybe there can be suggested another way, mabe simpler how to scaffold posts with tags and categories.
Thank you very much
Here are the models:
class Post < ActiveRecord::Base
belongs_to :category
belongs_to :user
attr_accessible :body, :title, :category, :user
end
class Category < ActiveRecord::Base
attr_accessible :name
end
class Serie < ActiveRecord::Base
attr_accessible :name, :website
end
class Tag < ActiveRecord::Base
attr_accessible :name
end
class TagsSerie < ActiveRecord::Base
belongs_to :serie
belongs_to :tag
# attr_accessible :title, :body
end
class TagsPost < ActiveRecord::Base
belongs_to :post
belongs_to :tag
# attr_accessible :title, :body
end
class User < ActiveRecord::Base
attr_accessible :email, :password
end
Add attr_accessible in your post model:
class Post < ActiveRecord::Base
attr_accessible :category_id, :user_id, :other_attributes_from_post_model
end
Try setting attr_accessible :category_id, :user_id in your post model.
By default, Rails creates the scaffolded models with all its attributes non-accessible, so they are not available to edit by an external user.
So, when you tried to create a new Post, the error message raised, as category and user are protected attributes of Post.
You should review your app/models/post.rb and the rest of your models in the same folder to define as accessible those attributes that should be editable by an external user (a web user, for instance).
class Post < ActiveRecord::Base
attr_accessible :category_id, :user_id
end
On the other hand, the so accessible attributes are not protected any more for external edition so you should not use attr_accessible for all of them but just for ones that you will really allow to be modified externally.
Hi I have three tables like the following:
class Workitem < ActiveRecord::Base
has_many :effort
attr_protected
end
class Effort < ActiveRecord::Base
attr_protected
belongs_to :workitem
belongs_to :person
end
class Person < ActiveRecord::Base
attr_accessible :given_name, :mgrid, :surname, :id
has_many :effort
end
The idea is to keep track of how many days a person has spent on a particular work item through efforts table. Could somebody verify if my relationships are correct? But this doesn't seem to work. Am I missing something here?
Also, I can't understand the has_many :through kind of associations. Can somebody please give me an idea if that is what I'm supposed to use in this case?
You would usually have the child as a plural object:
class Workitem < ActiveRecord::Base
has_many :efforts
attr_protected
end
class Person < ActiveRecord::Base
attr_accessible :given_name, :mgrid, :surname, :id
has_many :efforts
end
And I'd recommend using attr_accessible instead of attr_protected
If a Foo had many Bars and the Bars belonged to many Foos, it might look like this:
class Foo < ActiveRecord::Base
has_many :foo_bar
has_many :bars, through => :foo_bar
end
class Bar < ActiveRecord::Base
has_many :foo_bar
has_many :foos, through => :foo_bar
end
class FooBar
belongs_to :foo
belongs_to :bar
end
Something like that anyway. There's a load of help on Railcasts here
Also, there's a trillion examples on SO.
Hope that helps
I just created new columns in my database for my micropost table and these columns were vote_count comment_count and I want to connect it to the Vote models vote_up count and the Comment models comment count. Since I just added these columns although there were votes and comments, how do I connect these other models to the micropost model to fill in the new columns. Any suggestions are much appreciated!
Micropost Model
class Micropost < ActiveRecord::Base
attr_accessible :title, :content, :view_count
acts_as_voteable
belongs_to :school
belongs_to :user
has_many :comments
has_many :views
accepts_nested_attributes_for :comments
end
It looks like what you're trying to do is use a counter_cache, which rails supports, but you've got the names of the columns wrong.
You want to add a comments_count and a votes_count column to your database instead of the ones that you have.
Then you can hook it up to your models as follows:
class Micropost< ActiveRecord::Base
attr_accessible :title, :content, :view_count
acts_as_voteable
belongs_to :school
belongs_to :user
has_many :comments, :counter_cache => true
has_many :views
accepts_nested_attributes_for :comments
end
The votes half of it is a bit more tricky since you're using some extra code with your acts_as_votable module, but counter caches are the way that you want to go if I understand you correctly.
Here is more info on them: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
I am slowly getting the hang of Rails and thanks to a few people I now have a basic grasp of the database relations and associations etc. You can see my previous questions here: Rails database relationships
I have setup my applications models with all of the necessary has_one and has_many :through etc. but when I go to add a kase and choose from a company from the drop down list - it doesnt seem to be assigning the company ID to the kase.
You can see a video of the the application and error here: http://screenr.com/BHC
You can see a full breakdown of the application and relevant source code at the Git repo here: http://github.com/dannyweb/surveycontrol
If anyone could shed some light on my mistake I would be appreciate it very much!
Thanks,
Danny
You have setup your Kase and Company models as a one-to-one relationship (see http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html). This is probably not what you intended. Maybe if you could explain your intended relationship I could tell you where your mistake is?
class Company < ActiveRecord::Base
has_many :kases
has_many :people
end
class Kase < ActiveRecord::Base
belongs_to :company # foreign key: company_id
has_and_belongs_to_many :people # foreign key in join table
end
class Person < ActiveRecord::Base
has_and_belongs_to_many :kases # foreign key in join table
end
Relevant parts shown only. This should be a step in the right direction. You will need a join table for the many-to-many relationship, or alternatively, to model it using "has_many :through". Depends on whether you need to store other properties on the join. See link above for details.
I believe It should be
class Company < ActiveRecord::Base
has_many :people
has_many :kases
end
class Kase < ActiveRecord::Base
belongs_to :company
belongs_to :person
end
class Person < ActiveRecord::Base
belongs_to :company
has_one :kase
end
In your view (app/views/kases/new.html.erb) you have
<li>Company Select<span><%= f.select :company_id, Company.all %></span></li>
Try changing the select part to
<%= f.select :company_id, Company.all.collect {|m| [m.name, m.id]} %>
Suggestion
I also notice that you have four methods in your controller to find Kases by status. You can do this in your model, using named_scope. It's like this:
named_scope :active, :conditions => {:kase_status => 'Archived'}
And then, wherever you need to show only active Kases, you call Kase.active. The same for the other status.