我觉得我不知道自己在做什么......我有一个模糊的想法。我希望到目前为止我能做到这一点。
任何你可以看到重构的方法都将非常感激。
有一件事我注意到它确实是错误的是它会加载以前提交的正确选项,如果有错误并且它发布到同一个URL。文本输入似乎加载了先前的值,但是select和单选按钮重置为每次提交的默认值。
ResourcesController#新
def new
@resource = Resource.new
@title = "Submit Resource"
@categories = Category.all
end
ResourcesController #create(注意我在两个都有@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(model)
# == 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
我的资源#新表单的视图文件
<div class="field">
<%= f.label :category %>
<%= select_tag(:category_id, options_for_select(@categories.map {|c|[c.name, c.id]})) %>
</div>
最后一个问:我还没有使用过user_id字段。这将从设计中撤出,并将用户与提交的资源相关联。但是如何在不进行某种输入的情况下分配它,比如隐藏输入。这会在控制器的幕后进行吗?
答案 0 :(得分:1)
看起来创建操作有问题
def create
@title = "Submit Resource"
@categories = Category.all
@resource = Resource.new(params[:resource])
if @categories.collect(&:id).include?(params[:category_id].to_i)
@resource.category_id = params[:category_id]
end
@resource.user = current_user
if @resource.valid?
@resource.cost = params[:cost]
@resource.save
redirect_to root_url
else
render :action => :new
end
end
查看强>
<div class="field">
<%= f.label :category %>
<%= select_tag(:category_id, options_for_select(@categories.map {|c|[c.name, c.id]}, :selected => @resource.category_id)) %>
</div>
答案 1 :(得分:1)
到你的上一个问题:
devise添加一个current_user方法,该方法是登录用户。因此,如果用户拥有多个资源,您可以执行以下操作:
@resource = current_user.resources.new(params[:resource])
第一个问题:
当表单呈现时,它是基于@resource&amp; @categories变量。当您发布表单时,将调用create action来创建新的@resource。如果保存因任何原因失败,则使用新的@resource变量重新呈现表单。您遇到的问题是,再次显示表单时未设置@ resource.category。所以你必须在is_valid之前这样做吗?检查。
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.new(params [:resource])时设置类别。
检查控制台中的POST请求正文或其他内容,看看它是否嵌套在资源中。我不知道它的确切语法,但如果你改变它,你可以删除@ resource.category = Category.find行。
答案 2 :(得分:1)
要搭载Sandip,你可以使用before_filter
来干掉你的行动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
如果您打算在应用程序布局中粘贴@title,我会在您的视图中将@title更改为:
yield(:title) || 'My Site'
并在适当的页面上使用:
content_for(:title) do
Submit Resource
默认为“我的网站”。除非另有说明。