I have a form to edit a page, while it tells it's not a variable from what I have known from related questions. In view, an error is raised from this line:
<%= form_for #wiki, :url => giki_path(#wiki.name), :html => { :method => :put } do |f| %>
Where the #wiki does seem to be an instance, which can be confirmed by:
$ rails console
> #wiki
#<Gollum::Page:70026260995800 Home (markdown) #wiki="path/to/git/wiki/.git">
> #wiki.name
"/wiki/Home"
So I don't understand what is causing the problem:
undefined method `model_name' for #<Gollum::Page:0x007f6084d2bdb0>
Edit:
In controller:
# giki_controller.rb
def edit
#wiki = Wiki.find(params[:id])
end
# the same method, worked fine
def show
#wiki = Wiki.find(params[:id])
end
In model:
# wiki.rb
class Wiki
include ActiveModel::AttributeMethods
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :raw_data, :formatted_data, :title, :path, :change_desc, :versions
# Gollum Init
WIKI = Gollum::Wiki.new(Settings.wiki_repo, :base_path => "/wiki")
# initialize
def initialize(attributes = {})
attributes.each do |key, value|
send("#{key}=", value)
end
end
# no database
def persisted?
false
end
def self.find(name)
WIKI.page(name) # find a page by name
end
First lines from logger:
NoMethodError - undefined method `model_name' for #<Gollum::Page:0x007f607dfec4e8>:
actionpack (4.2.6) lib/action_controller/model_naming.rb:9:in `model_name_from_record_or_class'
actionview (4.2.6) lib/action_view/record_identifier.rb:47:in `dom_class'
Full traceback: I created a gist.
Your backtrace says that model_name is undefined in <Gollum::Page:0x007f607dfec4e8> which is an instance of Gollum::Page.
Reason
form_for method internally calls model_name method. This is actually a valid method name in ActiveRecord's instance.
Try
User.first.model_name
This model_name is not present in #wiki since this is not an instance of Wiki its rather the instance of Gollum::Page.
How can I say that?
Well, I saw you have overridden the self.find method in Wiki
def self.find(name)
WIKI.page(name) # find a page by name
end
so in your edit action, you have used find method to get the persisted instance, which will hand you over an instance Gollum::Page and this is not expected by form_for helper method.
Solution (Edited)
Well, if you were using ActiveRecord and wanted to continue the overridden self.find method then you can use where or find_by_x method instead in edit action. Like
def edit
#wiki = Wiki.find_by_id(params[:id])
end
But looks like you are not using ActiveRecord or your model is not derived from it, so you have to use the form_for method in different fashion.
If you don't need to attach a form to a model instance, then check out ActionView::Helpers::FormTagHelper#form_tag.
form_tag(giki_path(#wiki.name), method: :put)
Related
I have custom field in form_for
check_box_tag "files_to_delete[]", :attach.id
Permitted params:
params.require(:post).permit( ... , :files_to_delete => [])
I have before_action :some_method in my model, in which i want to have access to the files_to_delete:
def some_method
files_to_delete.each do |attach|
attach.clear
end
end
But i get:
undefined local variable or method `files_to_delete' for #<Post:0x007f5c4cb51ad0>
Your model needs a setter and getter for files_to_delete. Add the following line to your model:
attr_accessor :files_to_delete
When attempting to create on a model with CanCan set as manage: all I am continuously getting this error:
ActiveModel::ForbiddenAttributesError - ActiveModel::ForbiddenAttributesError:
I found a fix online here.
That pastes this code into my applications controller:
before_filter do
resource = controller_name.singularize.to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
This leads to my issue. I have two models with belongs_to_has_many association and a method that adds an user to a group.
When I want to add an user to a group using add_user which takes the group id and the user object I now get this error.
The routine is called by:
<%= link_to 'Add', add_user_group_path(group: #group, user_id: id) %>
The method looks like this:
def add_user
group = Group.find(params[:id])
user = User.find(params[:user_id])
group.users << user
end
And this is the error:
Parameters: {"group"=>"16", "id"=>"16", "user_id"=>"332"}
NoMethodError - undefined method `permit' for "16":String:
What is the before_filter method doing that would cause this error?
================ UPDATE ===================
I ended up figuring it out.
Since the group id is automatically passed in the add_user call from the controller I had to change this line:
<%= link_to 'Add', add_user_group_path(group: #group, user_id: id) %>
to:
<%= link_to 'Add', add_user_group_path(user_id: id) %>
And it now works. Turns out when you pass the #group object the param "group => x" gets parsed weird.
CanCan is not working with Rails4. Use CanCanCan, and you don't need any of these workaround. Just have some following methods just like what we normally do in Rails4.
create_params or update_params (depending on the action you are performing)
_params such as article_params (this is the
default convention in rails for naming your param method)
resource_params (a generically named method you could specify in each
controller)
Link Here: https://github.com/CanCanCommunity/cancancan
I have a model “Thing,” each of which has_many “Comments,” each of which in turn has_many “Votes.” I want to be able to vote on comments on the Thing show page. This is what I have so far:
Comments Controller:
def votecomment
#comment = Comment.find(params[:id])
Vote.create!(voteable_id: params[:id], voteable_type: 'Comment')
redirect_to current_thing
end
Things View:
<%= link_to “Vote”, vote_comment_path(:id => comment.id), method: :post %>
Routes:
post 'comments/:id/vote' => 'comments#vote', as: 'vote_comment'
But I'm getting back this error:
NameError in CommentsController#votecomment
undefined local variable or method `current_thing' for #<CommentsController:0x007f98efa69c00>
I tried moving the method to the Things controller, but I got the exact same type of error.
What am I doing wrong?
Assuming you have the following relation in comment.rb
belongs_to :thing
You can access the thing object of a comment using #comment.thing. Since redirect_to accepts objects, you can do
redirect_to #comment.thing
You have to understand that nothing is called current_thing if you are familiar with devise and you see ex current_user this is a method in the gem not a populated method with each model you create.
So if you want something like that add method to your application_controller or even application helper to get current_thing
def current_thing
Thing.find() --> or whatever the way you get that current thing.
end
I am using Mongoid(3.0.23) and I want to add nicer URL's, I have followed this rails cast but for some reason my site throws an undefined error for the find_by_slug method. I have read about some gems I could use but it seems pointless for such a simple task.
Model
validates :slug, :uniqueness => true
before_validation :generate_url
def generate_url
self.slug ||= self.title.parameterize if slug.blank?
end
def to_param
slug
end
field :slug
View
<% #events.each do |e| %>
<%= link_to e.title, event_path(e) %>
<% end %>
Controller
def show
#event = Event.find_by_slug!(params[:id])
end
Maybe try:
Event.find_by(slug: params[:id])
Also, not sure if it's necessary but you could specify the type:
field :slug, type: String
Mongoid defines the attribute finder, but not the bang version.
Event.find_by_slug(params[:id])
# => valid
Event.find_by_slug!(params[:id])
# => not defined
In any case, given the way ActiveModel is taking and according to best practices, it's better for you define all the public API of your model.
class Event
def self.find_by_slug!(slug)
where(slug: slug).first || raise(Mongoid::Errors::DocumentNotFound, self, slug: slug)
end
end
You can also re-use find_by_slug, but as I said, because ActiveRecord is deprecating find_by_attribute, I prefer to write the code directly.
I'm writing a ruby-on-rails library module:
module Facets
class Facet
attr_accessor :name, :display_name, :category, :group, :special
...
URI = {:controller => 'wiki', :action => 'plants'}
SEARCH = {:status => WikiLink::CURRENT}
#Parameters is an hash of {:field => "1"} values
def render_for_search(parameters)
result = link_to(display_name, URI.merge(parameters).merge({name => "1"}))
count = WikiPlant.count(:conditions => (SEARCH.merge(parameters.merge({name => "1"}))))
result << "(#{count})"
end
end
...
end
when I call render_for_search I get the error
undefined method 'link_to'
I've tried requiring url_helper directly but can't figure out what's going wrong.
Try this:
ActionController::Base.helpers.link_to
This is because, ActionView urlhelpers are only available to the Views, not in your lib directory.
the link_to method is found in the ActionView::Helpers::UrlHelper module, plus you wou
so try this.
class Facet
include ActionView::Helpers::UrlHelper
...
end
Simply including the helper doesn't get you much further. The helpers assume that they are in the context of a request, so that they can read out the domain name and so on.
Do it the other way around; include your modules in the application helper, or something like that.
# lib/my_custom_helper.rb
module MyCustomHelper
def do_stuff
# use link_to and so on
end
end
# app/helpers/application_helper.rb
module ApplicationHelper
include MyCustomHelper
end