Ruby on rails 我是否正确使用rails表单?
我觉得我不知道我在做什么。。我有一个模糊的想法。我希望到目前为止我做得很好 如果您能找到任何重构此文件的方法,将不胜感激 我注意到它的一个错误是,如果出现错误并发布到同一个URL,它将不会加载以前提交的正确选项。文本输入似乎加载上一个值,但选择和单选按钮在每次提交时重置为默认值 资源控制器新Ruby on rails 我是否正确使用rails表单?,ruby-on-rails,ruby,ruby-on-rails-3,refactoring,Ruby On Rails,Ruby,Ruby On Rails 3,Refactoring,我觉得我不知道我在做什么。。我有一个模糊的想法。我希望到目前为止我做得很好 如果您能找到任何重构此文件的方法,将不胜感激 我注意到它的一个错误是,如果出现错误并发布到同一个URL,它将不会加载以前提交的正确选项。文本输入似乎加载上一个值,但选择和单选按钮在每次提交时重置为默认值 资源控制器新 def new @resource = Resource.new @title = "Submit Resource" @categories = Category.all en
def new
@resource = Resource.new
@title = "Submit Resource"
@categories = Category.all
end
ResourcesControllercreate注意,我有@categories=Category.all在这两者中。。。根据DRY的说法,我不确定它还应该去哪里,或者它只在提交第一份表格时起作用
def create
@title = "Submit Resource"
@categories = Category.all
@resource = Resource.new(params[:resource])
category_ids = @categories.map { |c| c[1] }
if @resource.valid? and category_ids.include? params[:category_id]
@resource.cost = params[:cost]
@resource.category_id = params[:category_id]
@resource.save
redirect_to root_url
else
render :action => :new
end
end
Resource.rb模型
# == Schema Information
#
# Table name: resources
#
# id :integer not null, primary key
# upvotes :integer default(0)
# downvotes :integer default(0)
# url :string(255)
# title :string(255)
# cost :integer default(0)
# description :text
# flags :integer
# category_id :integer
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class Resource < ActiveRecord::Base
belongs_to :category
belongs_to :user
has_many :favorites
has_many :resource_tags
has_many :tags, :through => :resource_tags
attr_accessible :url, :title, :cost, :description, :category_id, :user_id
# Pseudo-Enum
COST = [:free, :paid, :both]
url_regex = /^(?:http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?$/ix
validates :url, :presence => true,
:format => { :with => url_regex,
:message => "must be valid"},
:uniqueness => { :case_sensitive => false,
:message => "has already been submitted"}
validates :title, :presence => true,
:length => { :within => 6..75 }
validates :cost, :presence => true
validates :description, :presence => true,
:length => { :within => 25..200 }
validates :category_id, :presence => true,
:format => { :with => /\d+/ }
validates :user_id, :presence => true,
:format => { :with => /\d+/ }
def cost
COST[read_attribute(:cost)]
end
def cost=(value)
write_attribute(:cost, COST.index(value.downcase.to_sym))
end
def category_id
read_attribute(:category_id).to_i
end
def category_id=(value)
write_attribute(:category_id, value.to_i)
end
end
Resourcenew表单的我的视图文件
<div class="field">
<%= f.label :category %>
<%= select_tag(:category_id, options_for_select(@categories.map {|c|[c.name, c.id]})) %>
</div>
最后一个问题:我还没有使用过user\u id字段。这将从Desive中提取,并将用户与提交的资源相关联。但是我如何分配它而不进行某种输入,比如隐藏输入。这会在控制器的后台进行吗?看起来创建操作有问题 看法 关于你的最后一个问题: Desive添加当前用户方法,即登录用户。因此,如果用户有多个资源,您可以执行以下操作:
@resource = current_user.resources.new(params[:resource])
第一个问题:
当呈现表单时,它是基于@resource&@categories变量进行呈现的。发布表单时,将调用创建操作,该操作将创建一个新的@resource。如果由于任何原因保存失败,则使用新的@resource变量重新提交表单。您遇到的问题是,再次显示表单时未设置@resource.category。所以你必须在你的申请有效之前这么做?检查
def create
@title = "Submit Resource"
@categories = Category.all
@resource = Resource.new(params[:resource])
@resource.category = Category.find(params[:category_id])
if @resource.valid? # won't be valid if there is no category found.
@resource.cost = params[:cost]
@resource.save
redirect_to root_url
else
render :action => :new
end
end
但真正的问题是你的状态。它应该在资源参数中嵌套category_id,以便在执行resource.newparams[:resource]时设置类别
检查控制台或其他地方的POST请求主体,看看它是否嵌套在资源中。我不知道它的确切语法,但是如果您更改它,您可以删除@resource.category=category.find行。要借助Sandip,您可以使用before\u过滤器来停止您的操作
class ResourcesController < ApplicationController
before_filter :load_categories, :only => [:show, :create]
def new
@resource = Resource.new
end
def create
@resource = Resource.new(params[:resource])
@resource.category = Category.find(params[:category_id])
if @resource.valid? # won't be valid if there is no category found.
@resource.cost = params[:cost]
@resource.save
redirect_to root_url
else
render :action => :new
end
end
private
def load_categories
@categories = Category.all
end
end
并在适当的页面上使用:
content_for(:title) do
Submit Resource
除非另有说明,否则它将默认为“我的网站”。谢谢,这看起来好多了,这是我最初想要做的,但我不知道collect&:id。但是。。。它似乎仍然没有加载以前的表单输入。
class ResourcesController < ApplicationController
before_filter :load_categories, :only => [:show, :create]
def new
@resource = Resource.new
end
def create
@resource = Resource.new(params[:resource])
@resource.category = Category.find(params[:category_id])
if @resource.valid? # won't be valid if there is no category found.
@resource.cost = params[:cost]
@resource.save
redirect_to root_url
else
render :action => :new
end
end
private
def load_categories
@categories = Category.all
end
end
yield(:title) || 'My Site'
content_for(:title) do
Submit Resource