在Rails 3中,可以将属性插入到params中,如下所示:
params[:post][:user_id] = current_user.id
Run Code Online (Sandbox Code Playgroud)
我试图在Rails 4中做类似的事情,但没有运气:
post_params[:user_id] = current_user.id
. . . .
private
def post_params
params.require(:post).permit(:user_id)
end
Run Code Online (Sandbox Code Playgroud)
Rails忽略了这种插入.它不会抛出任何错误,它只是悄然失败.
我有一个控制器,既响应html
和js
.该html
视图使得整个页面(包括页眉和页脚),而js
只替换#main
.除了页眉和页脚之外,两种格式都呈现相同的内容.我可以通过三个文件获得此效果:
_show.html.erb
<div>Content!</div>
show.html.erb
<%= render "show" %>
show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");
Run Code Online (Sandbox Code Playgroud)
这有效,但我更喜欢如果我不需要单独的_show
部分.不幸的是,这不起作用:
show.html.erb
<div>Content!</div>
show.js.erb
$("#main").fadeIn("<%= escape_javascript(render 'show') %>");
Run Code Online (Sandbox Code Playgroud)
由于Rails会查找show
部分视图,而不是实际视图.
有没有办法让Rails查找视图文件,而不是部分?
我有一个简单的模型:
class Reply < ActiveRecord::Base
attr_accessible :body
belongs_to :post
end
Run Code Online (Sandbox Code Playgroud)
在我的控制器中,我有一个简单的更新方法:
def update
@reply = Reply.find(params[:id])
if @reply.update_attributes!(params[:reply])
render :js => "alert('I am trying to update!')"
else
render :js => "alert('<%= @reply.errors %>')"
end
end
Run Code Online (Sandbox Code Playgroud)
这不会引发错误,但它实际上也不会更新回复.相反,我得到了"我正在尝试更新!" 消息,就像一切都有效.但是当我重新加载页面并查看回复时,它具有相同的文本.它实际上没有更新.如果我用以下内容替换update_attributes:
@reply.update_column(:body, params[:reply][:body])
Run Code Online (Sandbox Code Playgroud)
它工作正常.如果我使用:
@reply.update_attribute(:body, params[:reply][:body])
Run Code Online (Sandbox Code Playgroud)
它再一次无效.知道发生了什么事吗?
在我的日志中,我有这个:
Started PUT "/posts/2/replies/20" for 127.0.0.1 at 2013-01-19 10:39:57 -0600
Processing by RepliesController#update as JS
Parameters: {"utf8"=>"?", "authenticity_token"=>"Xot7E+ldXiBm0hVvw5XUP/U5guJU2g8e4QaLbDVGzDE=", "reply"=>{"body"=>"Updated text."}, "commit"=>"Submit Revision", "post_id"=>"2", "id"=>"20"
[1m[35mUser Load (1.0ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 …
Run Code Online (Sandbox Code Playgroud) 我关心的是我存储常量:
module Group::Constants
extend ActiveSupport::Concern
MEMBERSHIP_STATUSES = %w(accepted invited requested
rejected_by_group rejected_group)
end
Run Code Online (Sandbox Code Playgroud)
我希望使用这些常量的另一个问题是:
module User::Groupable
extend ActiveSupport::Concern
include Group::Constants
MEMBERSHIP_STATUSES.each do |status_name|
define_method "#{status_name}_groups" do
groups.where(:user_memberships => {:status => status_name})
end
end
end
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会导致路由错误:
uninitialized constant User::Groupable::MEMBERSHIP_STATUSES
Run Code Online (Sandbox Code Playgroud)
看起来第一个问题是在第二个问题中没有正确加载.如果是这样的话,我该怎么办呢?
我有两个模型加入了has_many:通过关系:
class Publication < ActiveRecord::Base
has_many :publication_contributors
has_many :contributors, :through => :publication_contributors
end
class Contributor < ActiveRecord::Base
has_many :publication_contributors
has_many :publications, :through => :publication_contributors
end
class PublicationContributor < ActiveRecord::Base
belongs_to :publication
belongs_to :contributor
end
Run Code Online (Sandbox Code Playgroud)
(关于我的PublicationContributor模型的一些不寻常和重要的是它不仅仅有一对数据库ID,它还有一个名为contributor_type的字符串属性.这个字符串可能包含诸如"Author"或"Translator"或"Publisher"之类的角色.我不相信这是问题,但解决方案仍然必须考虑到它.)
我想找一个具有特定贡献者的出版物,如下所示:
Publication
.joins(:publication_contributors => :contributor)
.where(:publication_contributors =>
{:contributor_type => "Author",
:contributor => {:name => params[:authors]}})
Run Code Online (Sandbox Code Playgroud)
一切正常,直到我进入嵌套:贡献者,此时SQL溅出:
Mysql2::Error: Unknown column 'publication_contributors.contributor' in 'where clause'
Run Code Online (Sandbox Code Playgroud)
它不是在寻找publication_contributors.contributor_id,而是在寻找不存在的publication_contributors.contributor.我在代码中做错了吗?我找不到像这样具有深层嵌套关联的where子句的任何其他示例.也许它甚至不可能?
更新:
生成的SQL
?[1m?[35mPublication Load (0.0ms)?[0m SELECT `publications`.* FROM `publicati
ons` INNER JOIN `publication_contributors` ON `publication_contributors`.`public
ation_id` = `publications`.`id` INNER JOIN `contributors` …
Run Code Online (Sandbox Code Playgroud) 我有一个属于许多不同模型的嵌套资源.例如:
resources :users do
resources :histories, only: [:show]
end
resources :publications do
resources :histories, only: [:show]
end
resources :events do
resources :histories, only: [:show]
end
Run Code Online (Sandbox Code Playgroud)
在HistoriesController
,我想找到父对象,虽然我很难想到一个干燥的方法来处理这个问题.目前,我能想到的最好的是:
if params[:user_id].present?
@parent = User.find(params[:user_id])
elsif params[:publication_id].present?
@parent = Publication.find(params[:publication_id])
elsif . . . .
Run Code Online (Sandbox Code Playgroud)
我有几十个模型,我必须以这种方式分支,这似乎很草率.我不考虑更好的(可能是烘焙的)方法吗?
我有一些访问商店的单元测试.我会认为这样会好的,只要我将它们包装在运行回调中.不幸的是,事实并非如此.我收到这个错误:
afterEach在#foo上失败:断言失败:您只能卸载不在飞行中的记录.
据我了解,这正是运行应该阻止的.我的测试看起来像这样:
test('#foo', function(assert) {
var store = this.store();
var model = this.subject();
Ember.run(function() {
var secondModel = store.createRecord('secondModel', { foo: 'bar' });
model.set('secondModel', secondModel);
var foo = model.get('secondModelFoo');
assert.equal(foo, 'bar');
});
});
Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个Rails插件.在大多数情况下,我所写的作品.然而,关联存在问题.当我尝试调用关联时,我收到此错误:
ActiveRecord::Base doesn't belong in a hierarchy descending from ActiveRecord
Run Code Online (Sandbox Code Playgroud)
目前,插件看起来像这样:
module ControlledVersioning
module ActsAsVersionable
extend ActiveSupport::Concern
included do
has_many :versions, as: :versionable
after_create :create_initial_version
end
module ClassMethods
def acts_as_versionable(options = {})
cattr_accessor :versionable_attributes
self.versionable_attributes = options[:versionable_attributes]
end
end
private
def create_initial_version
version = versions.create
end
end
end
ActiveRecord::Base.send :include, ControlledVersioning::ActsAsVersionable
Run Code Online (Sandbox Code Playgroud)
同样,每当我尝试调用关联时,都会触发错误消息.我在after_create
回调中使用了调试器并尝试运行:
> versions.create
*** ActiveRecord::Base doesn't belong in a hierarchy descending from ActiveRecord
> versions
*** ActiveRecord::Base doesn't belong in a hierarchy descending from ActiveRecord
> Version.new …
Run Code Online (Sandbox Code Playgroud) 每当我输入一个gem命令,比如
gem "tilt"
Run Code Online (Sandbox Code Playgroud)
要么
gem "mysql"
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
While executing gem ... <RuntimeError>
Unknown command tilt
Run Code Online (Sandbox Code Playgroud)
当我运行时gem list
,倾斜和mysql都显示在列表中,因此它们已安装.实际上,我在列表中的每个项目上都会出现此错误.可能是什么导致了这个?
在Rails 4中,可以将额外的参数与用户生成的参数合并,如下所示:
params.require(:post).permit([:title, :body]).merge(user: current_user)
Run Code Online (Sandbox Code Playgroud)
也可以包含嵌套属性,如下所示:
params.require(:post).permit([:title, :body, sections_attributes: [:title, :section_type]])
Run Code Online (Sandbox Code Playgroud)
现在,如果我想将额外参数合并到嵌套模型中,该怎么办呢?我试过这个:
params.require(:post).permit([:title, :body, sections_attributes: [:title, :section_type]]).merge(user: current_user, sections_attributes: [user: current_user])
Run Code Online (Sandbox Code Playgroud)
但是当我事后用调试器检查params时,我发现它user
已经覆盖了另一个section_attributes
而不是与它们合并.有没有更好的方法来解决这个问题?
Full backtrace
--------------
- activemodel (4.0.0.rc1) lib/active_model/attribute_methods.rb:436:in `method_missing'
- activerecord (4.0.0.rc1) lib/active_record/attribute_methods.rb:131:in `method_missing'
- activerecord (4.0.0.rc1) lib/active_record/nested_attributes.rb:432:in `block in assign_nested_attributes_for_collection_association'
- activerecord (4.0.0.rc1) lib/active_record/nested_attributes.rb:431:in `assign_nested_attributes_for_collection_association'
- activerecord (4.0.0.rc1) lib/active_record/nested_attributes.rb:322:in `comments_attributes='
- activerecord (4.0.0.rc1) lib/active_record/attribute_assignment.rb:42:in `_assign_attribute'
- activerecord (4.0.0.rc1) lib/active_record/attribute_assignment.rb:53:in `block in assign_nested_parameter_attributes'
- activerecord (4.0.0.rc1) lib/active_record/attribute_assignment.rb:53:in `assign_nested_parameter_attributes'
- activerecord (4.0.0.rc1) lib/active_record/attribute_assignment.rb:33:in `assign_attributes'
- activerecord …
Run Code Online (Sandbox Code Playgroud)