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
Related
Another user posts a problem, and I can click on that post to see details about that problem (not through show) and give a recommendation. The thing is that I don't want my recommendation to be linked with this problem. I want it to be linked with that user herself. To do this, I tried:
create
#recommendation = current_user.recommendations.build(recommendation_params)
#user = User.where(user: params[:user_id])
#recommendation.helped_id = #user.id
end
where helped_id should equate that user's id. (later I want that user to be able to see all recommendations she's been given)
But it's turning up error, saying
undefined method `id' for #<User::ActiveRecord_Relation:0x007ff6a9621f68> Did you mean? ids
UPDATE
So I go to the url where this other user's problem is detailed by this view code:
<% #users.each do |u| %>
<%= link_to new_recommendation_path(user_id: u.id) do %>
And the url is: http://localhost:3000/recommendations/new?user_id=2
Could this be the problem?
#user = User.find(params[:user_id]) works fine in new method for showing the problem, but the same code in create method returns cannot find.
You should use the find method which returns the object instead of a relation...
#user = User.find(params[:user_id])
It's possible to continue using AR Relation, so your code would be
#recommendation = current_user.recommendations.build(recommendation_params)
#user = User.where(id: params[:user_id]).first
#recommendation.helped_id = #user.id
Tip: In both scenarios, using User.find or User.where, you should take care of exceptional cases.
Using User.find, if user doesn't exist, then an ActiveRecord::RecordNotFound will be raised.
Using User.where, if user doesn't exist, then a NoMethodError (undefined method `id' for nil:NilClass) will be raised.
The solution was to add nested resources for user and recommendations
resources :users, shallow: true do
resources :recommendations
end
And, in the view, pass both user and recommendation parameters to the recommendation page.
<% #users.each do |u| %>
<%= link_to new_user_recommendation_path(u.id, #recommendation) do %>
Then #user = User.find(params[:user_id]) works.
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)
I'm trying to use gem breadcrumbs_on_rails.
I want to use the name attribute of my vehicle model in the current breadcrumbs element, so I'm using a Symbol as Breadcrumb Element, which calls the corresponding method defined in the same context and sets the Element attribute to the returned value (as per gem documentation).
#vehicles_controller.rb
def show
#vehicle = Vehicle.find(params[:id])
#user = User.find(params[:user_id])
add_breadcrumb "home", :root_path
add_breadcrumb "user profile", :current_user
add_breadcrumb :set_vehicle_name, :user_vehicle_path
end
...
private
#return vehicle name for breadcrumb
def set_vehicle_name
#vehicle.name
end
My view is as follow:
#vehicles/show.html..erb
<ol class="breadcrumb">
<%= render_breadcrumbs :separator => " / " %>
</ol>
When I run the server and access the page I get the following error:
NoMethodError in Vehicles#show
undefined method `set_vehicle_name' for #<#<Class:0x007f40edd52958>:0x007f40f18fe790>
Can you tell me what's causing this error? thanks
I made it working appending helper_method :set_vehicle_name after the private method definition, as specified in this post.
The gem uses the context of an ActionView::Base (breadcrumbs.rb#L25)
to evaluate any methods (breadcrumbs.rb#L50). It's complaining because
you haven't made your method in your controller available to the view.
Use helper_method to make it available to your views and it will work.
hope it might help
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'm setting up a follow system with the Rails Gem acts_as_follower and I've run into a problem I'm not sure how to fix.
When I go to follow for example a user with the username of 'testuser1' I get this error:
Couldn't find Member with id=testuser1
app/controllers/follows_controller.rb:6:in `create'
Parameters:
{"_method"=>"post",
"authenticity_token"=>"FnqLCCQYcFGMerOB56/G6dlPvzpPhPDFbxCXaiDBOUU=",
"member_id"=>"testuser1"}
Here's my Controller:
class FollowsController < ApplicationController
before_filter :authenticate_member!
def create
#member = Member.find(params[:member_id])
current_member.follow(#member)
end
def destroy
#member = Member.find(params[:member_id])
current_member.stop_following(#member)
end
end
The form to create the follow:
<%= link_to("Follow", member_follows_path(member.to_param), :method => :post, :class => "btn") %>
<%= link_to("Following", member_follow_path(member.to_param, current_member.get_follow(member).id), :method => :delete, :class => "btn btn-follow") %>
And this is how I've defined my to_param since that's how you get to a member/user's page:
def to_param
user_name
end
Anyone out there know how I can go about fixing this? Thanks.
Remove the to_param. When you're using the URL helpers, such as your member_follows_path, you need to pass the ID, or from the ERB's perspective, the object itself (it'll resolve to the ID when the ERB renders)
Alternatively, in your rails controller, change the find to something like find_by_user_name, or whatever the field is supposed to be, and then that line should work. Beware that this will be slower, especially if you have a large database without proper indexing / partitioning.