markdown Rails中的多态性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Rails中的多态性相关的知识,希望对你有一定的参考价值。
### Polymorphism in Rails
---
* Allows you to have a model **associated with more than one other model without the use of a join table**
* How?
* Adding a **type** and **id** field to the table of the model you wish to make polymorphic
* When creating the association using `rails g` and appending **name:references{polymorphic}**
can be used to quickly establish the `_type` and `_id` polymorphic column names (all done by Rails).
* Convention is to '-able' to the polymorphic attribute.
---
#### Example: Person, Business & Interaction
* Interactive will belong to an Interaction which Person and Business will have many of:
```ruby
rails g model Person first_name last_name
rails g model Business name
rails g model Interaction description interactive:references{polymorphic}
# you can use any name for the polymorphic id and type, just as long as they make sense
rake db:migrate
```
* Add to Person and Business class (keep Interaction class the same)
```ruby
class Person < ApplicationRecord
has_many :interactions, as: :interactive
end
class Business < ApplicationRecord
has_many :interactions, as: :interactive
end
# This should defaulted by rails
class Interaction < ApplicationRecord
belongs_to :interactive, polymorphic: true
end
```
* If you open `rails c` and then entered `Interaction.column_names`, you will see:
* `interaction_id`: holds the **id** of the model that the interaction belongs to
* `interaction_type`: holds the **type** of the model that the interaction belongs to
* Both tell Rails which model this interaction should be associated with
* Adding the following controllers:
```ruby
# in terminal
rails g controller People index show new create edit update
rails g controller Businesses index show new create edit update
rails g controller Interactions new create edit update
```
* **Nest your resources** such that the polymorphic association is nested within each model!
* You will need some way to **parse** which object the polymorphic association belongs to:
* Checking the **params** for the object's class and then **returning** the object in the db
```ruby
class InteractionsController < ApplicationController
def new
@context = context
@interaction = @context.interactions.new
end
def create
@context = context
@interaction = @context.interactions.new(interaction_params)
if @interactions.save
redirect_to context_url(@context), notice: "The interaction has been successfully created."
end
end
def edit
@context = context
@interaction = @context.interactions.find(params[:id])
end
def update
@context = context
@interaction = @context.interactions.find(params[:id])
if @interaction.update_attributes(interaction_params)
redirect_to context_url(@context), notice: "The interaction has been successfully updated."
end
end
private
def interaction_params
params.require(:interaction).permit!
end
def context
if params[:person_id]
id = params[:person_id]
Person.find(params[:person_id])
else
id = params[:business_id]
Business.find(params[:business_id])
end
end
def context_url(context)
if Person === context
person_path(context)
else
business_path(context)
end
end
end
```
* For your forms that use the polymorphic association:
```ruby
<%= form_for [obj1, obj2] do %>
#...
<% end %>
```
* `obj1` is the object returned from parsing the polymorphic association (ex. @context = context)
* `obj2` is the object of the polymorphic class (ex. Interaction.new)
---
# Checking in Rails Console
* Seed the database with Person and Business objects.
* In `rails console`:
```ruby
p = Person.first
p.interactions.build(description: "asdfgh asdf").save
p.interactions.first.interactive_type
# returns "Person"
p.interactions.first.interactive_id
# returns the corresponding id of the Person object
# Now that you have an interaction, you can call the method interactive on the Interaction object to retrieve
# it's parent:
i = Interaction.first
i.interactive # returns the corresponding parent object (Person in this case)
```
* You build the polymorphic relationship by calling **build** on the model that has_many of the polymorphic
association.
* You'll then have access to the id and type of the object!
以上是关于markdown Rails中的多态性的主要内容,如果未能解决你的问题,请参考以下文章
markdown 如何解决Rails(OSX)中的OpenSSL错误?
markdown Rails任务(Ruby中的学生注册).md