How to create working controllers for new activity_objects?

99 views
Skip to first unread message

Ted Cohn

unread,
Jun 14, 2013, 1:25:49 AM6/14/13
to social...@googlegroups.com
I've created a new activity object per documentation but I'm unable to create a working controller that does not fail in create/update with. The documentation is so poor, it's been extremely frustrating and is hard to continue, but hoping I can get past the basics soon before I give up. Can someone please post a template on how to property create a new activity object with working controller? I've scoured the engine for examples, and they are all cryptic and nothing works for me. Also, can someone please explain the meaning of these fields: 

user_author_id
owner_id
author_id
relation_ids

Thanks.

murky...@gmail.com

unread,
Jun 15, 2013, 12:29:36 AM6/15/13
to social...@googlegroups.com
what errors are you getting?

Carlos García Quiñones

unread,
Jun 15, 2013, 5:32:07 AM6/15/13
to social...@googlegroups.com
Hi Ted,

I'm not an expert but I'll try to explain it:

First, you'll need to set up social_stream. I assume you're working with latest rails (3.2). This is well documented, but that will be:

rails new project
cd project
[[configure your database in config/database.yml]]
add to your Gemfile: gem social_stream
bundle install
rails generate social_stream:install

You can create your model/controller/views as always in a rails application. For instance, for a 'Documentation' object:

rails g scaffold Documentation title:string number_of_pages:integer

Then you'll need to add this newly created model as a social_stream activity object. In config/initializers/social_stream.rb:
'''config.objects += [:documentation]'''

You'll need to add an activity_object_id attribute to the new model, to reference social_stream activities. Edit your new migration in db/migrate and add the second line here:
''''
  create_table :documentations do |t|
    t.integer :activity_object_id ## or t.references :activity_object
    t.string :title
    t.integer :number_of_pages
    t.timestamps
  end
'''

Now, you can create your database:
rake db:create
rake db:migrate

This model has to implement the SocialStream::Models::Object interface (module). So, in app/models/documentation.rb:
'''
class Documentation
  include SocialStream::Models::Object
  ....
'''
And in the controller (app/controller/documentations_controller.rb):
'''
class DocumentationsController
  include SocialStream::Controller::Objects
  ...
'''
--

Now, in documentation creation...: ( create method in the controller )

Since social_stream uses strong parameters gem (you can look at this gem documentation to see it clearer), you'll need to set the params variable filter, before creating the new object.
Like this:
'''
def create
  documentation = Documentation.new(documentation_params)
  ...

end
...

private
def documentation_params
  params.require('documentation').permit('title', 'number_of_pages')
end
'''

The attributes you were talking about... I'm not completely sure, but this is what I think they mean right now:

'owner_id' is the id of the 'Actor'  that has complete permissions over the object.
'author_id' is the id of the 'Actor' that created the object. It can be a 'User' or a 'Group'. (they are sort of ''subclasses'' of Actor)
'user_author_id' is the id of the 'Actor' that created the object. When the author is a group, user_author stores the user that was logged in the creation moment. Maybe I'm wrong in this, please correct me if it is so.

You'll have to set this attributes before you save the model. So...either you set some hidden_fields in the views (and add this attributes to the params filter!), which I don't do, or you can do:
'''
def create
  documentation = Documentation.new(documentation_params)
  documentation.owner_id = documentation.author_id = documentation.user_author_id = Actor.normalize_id(current_user)
  if documentation.save
    redirect_to documentation, :notice => 'successfully saved'
  else
    render :new, :error => documentation.errors
  end
end
'''

I think this is not the best way to do it, but you'll have it working... you can think later of better ways to assing these attributes.
Someone will have to answer about what 'relation_ids' is, because I don't know :-O

Hope this helps!

Carlos
Message has been deleted

Carlos García Quiñones

unread,
Jun 15, 2013, 7:23:02 AM6/15/13
to social...@googlegroups.com
Well, latest rails is not 3.2, but I think social_stream is not working yet with the pre-release version of rails 4... so I added this to my Gemfile:

gem rails, '~> 3.2'

Ted Cohn

unread,
Jun 15, 2013, 9:25:45 PM6/15/13
to social...@googlegroups.com
Carlos, thank you so much. I was able to get it working with your help. I think it was setting the the owner information correctly that waas the problem. And thanks for the explanation.
Cheers,
Ted

On Thursday, June 13, 2013 10:25:49 PM UTC-7, Ted Cohn wrote:

Antonio Tapiador del Dujo

unread,
Jun 17, 2013, 5:55:05 AM6/17/13
to social...@googlegroups.com
Carlos, thank you very much for this detailed explanation. It would be wonderful if you could update the wiki page with this information:

https://github.com/ging/social_stream/wiki/How-to-add-new-activity-objects

Regarding your questions, you are right in the definition of owner, author and user_author. The SocialStream::Controller::Objects already provides a before_filter for this. Be aware that, if you rely on hidden_fileds, users could forge the author of the objects. This must be set in the controller.

https://github.com/ging/social_stream/blob/master/base/lib/social_stream/controllers/objects.rb#L80

Besides, the SocialStream::Controller::Objects provides a method to filter strong_parameters attributes. You just have to define the allowed_params method in the controller, see:

https://github.com/ging/social_stream/blob/master/base/lib/social_stream/controllers/objects.rb#L100

El 15/06/13 11:32, Carlos García Quiñones escribió:
--
You received this message because you are subscribed to the Google Groups "Social Stream" group.
To unsubscribe from this group and stop receiving emails from it, send an email to social-strea...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Carlos García Quiñones

unread,
Jun 17, 2013, 7:28:52 AM6/17/13
to social...@googlegroups.com
Oh, great, that greatly simplifies my controllers.

I have been able to remove the 'create' action from my controller because I have moved what I was doing there to a before_filter.
So, now, I have:

  class DocumentationController < ApplicationController
    include SocialStream::Controllers::Objects
    before_filter :specific_action, only: [:create, :update]
    ...

However, if that wasn't possible or I didn't want to do it like this, how would I shape my 'create' action?

I have tried something like:

  def create
    set_author_ids
    @documentation = Documentation.new(whitelisted_params)
    if @documentation.save
      redirect_to documentation_path ....
    else
      render :new 
    end
  end

And this doesn't work. The error message is: author and user_author cannot be blank.
I also tried using the before_filter :set_author_ids with the same result...  
 
And, a second question... is the use of 'whitelisted_params' in the latter code correct? I think it is ortogonal to the other error because I also tried changing it to params.require(..).permit(...).


I will update the wiki, of course, after this gets clearer for me :)

Antonio Tapiador del Dujo

unread,
Jun 18, 2013, 5:18:11 AM6/18/13
to social...@googlegroups.com
Hi Carlos, I think the method you propose is right. I would have to debug it to find out why it is not working, because using "whitelisted_params" should work

In any case, I am upgrading to inherited_resources ~> 1.4.0, which recommends to use the method "permitted_params". So "whitelisted_params" method will change to "permitted_params" in the next version of social stream. This will not affect to the API, as the "allowed_params" method remains the same.



El 17/06/13 13:28, Carlos García Quiñones escribió:

Carlos García Quiñones

unread,
Jun 18, 2013, 5:35:14 AM6/18/13
to social...@googlegroups.com
Hi Antonio, thanks for the info!
I think whitelisted_params is working ok, I just wanted to check whether this was the intended way to do it.
'set_author_ids' is not working for me, though (not as a before_filter in my controller or calling it before creeating the object).
It doesn't really matter, I assign the owner/author/user_author manually.
I'll update the wiki now, and reupdate it when the upgrade to inherited_resources is done (to change whitelisted_params to permitted_params).

Cheers,

 Carlos

Antonio Tapiador del Dujo

unread,
Jun 18, 2013, 6:07:59 AM6/18/13
to social...@googlegroups.com
Thank you Carlos. The change to permitted_params is already released in v2.0.4

El 18/06/13 11:35, Carlos García Quiñones escribió:

Carlos García Quiñones

unread,
Jun 18, 2013, 7:23:19 AM6/18/13
to social...@googlegroups.com
Great, I already changed the wiki with permitted_params. Feel free to modify if there is a better way to do it.

Antonio Tapiador del Dujo

unread,
Jun 18, 2013, 8:09:08 AM6/18/13
to social...@googlegroups.com
Awesome Carlos! Thank you!

El 18/06/13 13:23, Carlos García Quiñones escribió:

Alejandro Cacho

unread,
Jun 12, 2014, 6:34:15 AM6/12/14
to social...@googlegroups.com
Hi there!

First of all congrats for the engine, I think it's great, and I hope between all could do it better.

I have different problems related with this issue:

The first problem is related with the generation of a new activity. In this case, and for simplicity, I will continue with the example of Documentation.

I have done the scaffold, added the lines to the model and the controller ( include SocialStream::Controllers::Objects etc and include SocialStream::Models::Object).
I have also added the reference to activity object and added  config.objects += [:documentation] to the social_stream.rb initializer file, so all the steps are finished.

Now, I want to be able to access to that new activity acceding from the toolbar. I have saw on config/social_stream.rb this at the end of the file:

# You can customize toolbar, sidebar and location bar from here

# See https://github.com/ging/social_stream/wiki/How-to-customize-the-toolbar,-sidebar-and-location


But that link throw me an error (You do not have permission to update this wiki.) so I suppose It hasn't been created yet. I have then try to figure out myself how to added, so in

app/views/toolbar/_profile.html.erb I have added a link similar to the profile and repository ones:


<li>

<%= link_to [ subject, :documentation ] do  %>

<i class='icon_tool16-info'></i> <%= t 'menu.documentation' %>

<% end %>

</li>



In is here where we find my first problem: the route is generated bad. Instead of a route like localhost:3000/users/usuario/repository or localhost:3000/users/asdf/repository it creates a route like localhost:3000/users/asdf/documentations/usuario. It then throws an error, as doesn't exist a documentation with id="asdf":

ActiveRecord::RecordNotFound in DocumentationsController#show

Couldn't find Documentation with id=asdf


How do Social Stream create the routes? How can I fix it? In this case, if I try to click on the other links (repository, profile) they still don't work, throwing me the error:

Routing Error

No route matches {:action=>"show", :controller=>"documentations", :user_id=>#<User id: 1, encrypted_password: "$2a$10$wQiZGT1KXpYjD3zf57pQneI4wxP5t5zxJB7C.XeQumjS...", password_salt: nil, reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 8, current_sign_in_at: "2014-06-12 08:26:55", last_sign_in_at: "2014-06-11 08:15:57", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", authentication_token: nil, created_at: "2014-06-09 10:51:56", updated_at: "2014-06-12 08:26:55", actor_id: 1, language: nil, connected: false, status: "available", chat_enabled: true, role: 0>}

Try running rake routes for more information on available routes.

Why this appends if I haven't touched the other links? Moreover, that links are still correct on the browser.



My second problem is related with that. If I put on my browser the URI localhost:3000/users/usuario/documentations it works fine. It shows me that I have no documentation (normal scaffold generated page). So I decide to create a new one. It goes to http://localhost:3000/documentations/newI introduce the fields, and when I press "Create New" it throws an error:

Can't mass-assign protected attributes: author_id, user_author_id, owner_id

This is my create method in Documentation_controller:

  def create

    @documentation = Documentation.new(documentation_params)


    params['documentation']['owner_id'] = current_subject.try(:actor_id)

    params['documentation']['author_id'] = current_subject.try(:actor_id)

    params['documentation']['user_author_id'] = current_user.try(:actor_id)


    # @documentation.owner_id = @documentation.author_id = @documentation.user_author_id = Actor.normalize_id(current_user)

    if @documentation.save

    # redirect_to documentation, :notice => 'successfully saved'

    else

    # render :new, :error => documentation.errors

    end

  end


As you can see in the commented line, I have also tried the sintaxis commented on this post and it still doesn't work.
(@documentation.owner_id = @documentation.author_id = @documentation.user_author_id = Actor.normalize_id(current_user))

I have this in the private part of my class:

  def documentation_params

    params.require(:documentation).permit(:number_of_pages, :title)

  end


  def allowed_params

    [:number_of_pages, :title]

  end


But it still throws the same error. Am I missing something?


Thank you very much!

Brainstorm

unread,
Jun 12, 2014, 11:19:36 AM6/12/14
to social...@googlegroups.com
Guys I have the same problem like Alejandro, someone can help us ? 
Reply all
Reply to author
Forward
0 new messages