How can I take advantage of my model associations in my view and controller in Ruby on Rails 3?
I am new to Rails and am trying to set up my Models and was wondering how Rails handles associations.
I have a Quest object which "belongs_to" or references via foreign keys a number of other objects, including User and Content:
quest.user_id
quest.a_different_name_id #this is a foreign key to a Content object
these are both foreign keys referencing a User object and Content object respectively.
Both User and Content "has_many" Quests.
I understand that this setup allows me to do things like:
u = User.create #saves to database
u.quests.build #creates new Quest object with user id set to u.id
Can I do something in the opposite direction like:
form_for @quest do |f|
f.text_field :a_user_attribute #an attribute of a User object
开发者_Go百科 f.text_field :a_different_name_attribute #an attribute of a Content object
where the form has text fields for the attributes of the objects which a Quest object references through its foreign keys as opposed to having a form for the actual foreign keys, so that when in the controller I have:
@quest = Quest.new(params[:quest])
Is Rails smart enough to "reach through" the model-defined foreign key relationships and populate and then save the User and Content objects and appropriately set the foreign keys in @quest to reference the newly created objects?
Can it do this even though the foreign key for the Content object has a different name than content_id?
Hope this makes sense... let me know if I am being unclear.
You can do what you need with the Nested Attributes feature in Rails http://guides.rubyonrails.org/2_3_release_notes.html#nested-attributes
Check out the form helper for it here http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
Basically you would need to do the following:
class User < ActiveRecord::Base
has_many :quests
accepts_nested_attributes_for :quests
...
end
class Quest < ActiveRecord::Base
belongs_to :user
...
end
then in the form you do the following:
<%= form_for @user do |f| %>
UserAttrA : <%= f.text_field :a_user_attribute_a %>
UserAttrB: <%= f.text_field :a_user_attribute_b %>
<%= f.fields_for :quests do |qf| %>
QuestAttrA : <%= qf.text_field :a_quest_attribute_a %>
QuestAttrB: <%= qf.text_field :a_quest_attribute_b %>
<% end %>
UserAttrC : <%= f.text_field :a_user_attribute_c %>
UserAttrD: <%= f.text_field :a_user_attribute_d %>
<% end %>
And your controller would work just like you have above.
Note that you can display User inputs before and/or after Quest inputs. Basically you can make the form in the view look how you want. But the semantics on the server will be need to be consistent.
精彩评论