与对象有关的form_for

form_for基本形态

#基本形态
#config/routes.rb
resources :articles
#views,省略url
<%= form_for @article do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :body, size: "60x12" %>
  <%= f.submit "Create" %>
<% end %>

#省略url,智能识别@article
@article.new_record? #=>true, url: articles_path, method: :post 备注:articles_path, method: :post路径,就是创建新的记录
@article.new_record? #=>false, url: article_path(@article), method: :patch

#自己指定url和html
<%= form_for @article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>

#处理put,patch,delete
浏览器只能识别get和post请求,对于其他请求均以hidden字段提交
#示例
form_tag(search_path, method: "patch")
#html代码
<form accept-charset="UTF-8" action="/search" method="post">
  <input name="_method" type="hidden" value="patch" />
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
  ...
</form>

#处理namespace
#config/routes.rb
namespace :admin do
  resources :articles
end
#view
form_for [:admin, @article]

使用collection_select处理隐式单选

#使用collection_select进行单选
#示例
rails g scaffold tag name
rails g scaffold article name address tag:references
#tag.rb
class Tag < ApplicationRecord
  has_many :articles, dependent: :destroy
end
#article.rb
class Article < ApplicationRecord
  belongs_to :tag
end
#view中显示
<%= form_for @article do |f| %>
  <%= f.label :tag %>
  #最开始的值是tag_id, 第二个是Tag.all, 第三个是Tag.all的id值,最后一个是呈现在view中的name属性,也可以选择address属性
  <%= f.collection_select :tag_id, Tag.all, :id, :name %>
  #<%= f.collection_select :tag_id, Tag.all, :id, :address %>
  #<%= f.collection_select :tag_id, Tag.all, :id, :name, prompt: "请选择" %>
<% end %>

使用collection_radio_boxes处理显式单选

#使用collection_radio_buttons处理单选显示形式
<%= form.collection_radio_buttons :tag_id, Tag.all, :id, :name %>

使用collection_check_boxes处理多选

#示例代码
rails g scaffold product name:string 
rails g scaffold category name:string
rails g scaffold categorization product:references category:references

#model
class Categorization < ApplicationRecord
  belongs_to :product
  belongs_to :category
end
class Category < ApplicationRecord
  #注意,次序不能变,has_many必须在has_many: through之前
  has_many :categorizations, dependent: :destroy
  has_many :products, through: :categorizations, dependent: :destroy
end
class Product < ApplicationRecord
  has_many :categorizations, dependent: :destroy
  has_many :categories, through: :categorizations, dependent: :destroy
end

#controller
def product_params
  params.require(:product).permit(:name, {category_ids: []})
end

#view中使用collection_check_boxes
<div class="field">
  <%= form.label :categories%>
  <%= form.collection_check_boxes :category_ids, Category.all, :id, :name %>
</div>

选择tag的过程中创建tag

#辅助代码如上所示
#创建虚拟属性,定义方法
class Product < ApplicationRecord
  attr_accessor :new_category_name
  validates :new_category_name,
    format: { with: /\A[\u4e00-\u9fa5\w,,]+\z/, message: "只接受数字,中文,英文和逗号" },
    allow_blank: true
  #必须product创建之后才创建,所以使用after_save
  after_save :create_category_from_name,
    unless: Proc.new { |product| product.new_category_name.blank? }

  private
    def create_category_from_name
      if new_category_name.include?(",") && new_category_name.include?(",")
        new_category_name.split(",").each do |category|
          unless category.include?(",")
            unless Category.exists?(name: category.strip)
              categories.create(name: category.strip)
            else
              categories << Category.find_by(name: category.strip)
            end
          else
            category.split(",").each do |category|
              unless Category.exists?(name: category.strip)
                categories.create(name: category.strip)
              else
                categories << Category.find_by(name: category.strip)
              end
            end
          end
        end
      elsif new_category_name.include?(",")
        new_category_name.split(",").each do |category|
          categories.create(name: category.strip)
          unless Category.exists?(name: category.strip)
            categories.create(name: category.strip)
          else
            categories << Category.find_by(name: category.strip)
          end
        end
      elsif new_category_name.include?(",")
        new_category_name.split(",").each do |category|
          unless Category.exists?(name: category.strip)
            categories.create(name: category.strip)
          else
            categories << Category.find_by(name: category.strip)
          end
        end
      else
        unless Category.exists?(name: new_category_name.strip)
          categories.create(name: new_category_name.strip)
        else
          categories << Category.find_by(name: new_category_name.strip)
        end
      end
    end
end

#controller
def product_params
  params.require(:product).permit(:name, :new_category_name, {category_ids: []})
end

#view中
<div class="field">
  <%= form.label "创建tags" %>
  <%= form.text_field :new_category_name %>
</div>

results matching ""

    No results matching ""