I'm getting this error:
`@namespace/model' is not allowed as an instance variable name
When I try to do this:
<%= in_place_editor_field :'namespace/model', :name %>
To reproduce:
> rails t; cd t
> ./script/generate model Namespace::Model
class CreateNamespaceModels < ActiveRecord::Migration
def self.up
create_table :namespace_models do |t|
t.column 'name', :text
end
end
def self.down
drop_table :namespace_models
end
end
development:
adapter: sqlite3
database: db/development.sqlite
> rake db:migrate
> ./script/generate controller whatever
class WhateverController < ApplicationController
in_place_edit_for :'namespace/model', :name
def index
@namespace__model = Namespace::Model.find_or_create_by_name('Tyler')
end
end
app/views/layouts/whatever.rhtml
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<%= javascript_include_tag :defaults %>
</head>
<body>
<%= yield %>
</body>
</html>
app/views/whatever/index.rhtml
<%= in_place_editor_field :'namespace/model', :name %>
To test it against edge Rails, I also did this:
> rake rails:freeze:edge
Exported revision 6838.
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- active_resource (MissingSourceFile)
Neat!
http://ryandaigle.com/articles/2007/4/26/activeresource-available-as-a-gem/comments/2362#comment-2362
> gem install activeresource --source http://gems.rubyonrails.org --backtrace
ERROR: While executing gem ... (NoMethodError)
undefined method `source_index' for #<Hash:0xb7d89bc4>
Neat!
config.frameworks -= [ :action_web_service, :action_mailer, :active_resource ]
config.action_controller.session = { :session_key => "_myapp_session", :secret => "some secret phrase" }
Proposed solution:
# Based on lib/facets/core/string/methodize.rb
class String
def methodize
gsub(/([A-Z])/, '_\1').downcase.gsub(/^_/,'').gsub(/(::|\/)_?/, '__')
end
end
# File vendor/rails/actionpack/lib/action_controller/macros/in_place_editing.rb, line 23
module ActionController::Macros::InPlaceEditing::ClassMethods
def in_place_edit_for(model_class, attribute, options = {})
model_class = model_class.to_s.camelize.constantize unless model_class.is_a?(Class)
define_method("set_#{model_class.name.methodize}_#{attribute}") do
@item = model_class.find(params[:id])
@item.update_attribute(attribute, params[:value])
render :text => @item.send(attribute)
end
end
end
# File vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb, line 78
module ActionView::Helpers::JavaScriptMacrosHelper
def in_place_editor_field(model_name, method, tag_options = {}, in_place_editor_options = {})
model_class = model_name.to_s.camelize.constantize unless model_class.is_a?(Class)
methodized_name = model_class.name.methodize
tag = ::ActionView::Helpers::InstanceTag.new(methodized_name, method, self)
tag_options = {:tag => "span", :id => "#{methodized_name}_#{method}_#{tag.object.id}_in_place_editor", :class => "in_place_editor_field"}.merge!(tag_opt
in_place_editor_options[:url] = in_place_editor_options[:url] || url_for({ :action => "set_#{methodized_name}_#{method}", :id => tag.object.id })
tag.to_content_tag(tag_options.delete(:tag), tag_options) +
in_place_editor(tag_options[:id], in_place_editor_options)
end
end
I don't feel up to the task of writing an automated test for it currently, but I have confirmed that it works in the test app described above.
Related error: Could not find table 'models'
def index
Namespace::Model.find_or_create_by_name('Tyler')
end
Could not find table 'models'
Shouldn't it use 'namespace_models' by default? Or is that only if #6792 gets applied? The workaround for now is obviously:
# app/models/namespace/model.rb
class Namespace::Model < ActiveRecord::Base
set_table_name 'namespace_models'
end
Related error: Called id for nil, which would mistakenly be 4
If you forget to set an instance variable (or misspell something), you currently get this really unhelpful error :
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
I propose this change:
# vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
class ActionView::Helpers::InstanceTag
def object
@object || @template_object.instance_variable_get("@#{@object_name}") || raise("Could not find instance variable named @#{@object_name} in template")
end
end
which would produce this:
Could not find instance variable named @namespace__model in template
(Should I open a separate ticket?)
See also:
#6792:
"Since 1.2 will offer better support for models placed in modules, ..."
Module names are now used as table_name prefixes, so Content::Folder.table_name will be 'content_folders'. The (last) module name will be singular, the class name will be plural by convention.
So are we moving to using demodulize on inheritance types, or towards not using it? I would prefer the latter.
We're not using demodulize on types from now on. That's how it should work and it truly allows namespaces, also at the db/table level.
#4484: "This is a patch to allow in_place_edit_for to support a :class_name option, allowing more flexibility for instance variable naming in views." (Might be another alternative solution to this problem. Although I'd prefer just to have a sensible default behavior.)
#7557: "Out of interest, why does ActiveRecord demodulize the class name before stuffing it in the type field?" (Why does it demodulize ... Wouldn't it be best to always keep the full scope?)