Is there a way to access a single element in an many to many ActiveRecord association via form? - ruby-on-rails-6

Hello Ruby on Rails professionals out there!
In a project we work with Ruby on Rails (version 6.1.1) and we have a database model with the associations as in the screenshot (Database UML with ActiveRecord Associations). This UML diagram shows three models in Ruby, Task, UserTask and User.
UserTask has an ID, task_id as foreign key (via association belongs_to :task) and user_id as foreign key (via association belongs_to :user). It also has an ActionText linked to it, it is called personal_note and according to the guide on rubyonrails.org it has the association has_rich_text :personal_note.
Task has the association has_many :user_tasks and has_many :users, through: :user_tasks.
User has the association has_many :user_tasks and has_many :tasks, through: :user_tasks.
I was neither able to define a specific UserTask using the current user nor to define a specific UserTask using the current task of a user.
In the form, where we edit the task, we want to also update the personal_note of the current user. But when saving I receive the following error:
Unpermitted parameter: :user_task
I tried lots of changes with singular and plural, with where conditions and where combined with first and also creating methods that filter the element. Though I wasn't able to fix that and now I have no clue how this may work (or in fact, is there just no way it works at all?). Maybe someone else here has an idea.
You can find the project code in Github, it's in it's own branch.
Thank you in advance for any suggestions.

Related

Audit.Net Entity Framework - Independant Associations [Tables Many-To-Many]

Hi i write because i have configured the Audit for one single table for all my entities and its working fine for the general tables in my model, but with the Many-To-Many tables i don't know how can i do for setup the "AssociationEntryRecord"? the event is fired by EF when i do one change in this tables but i don't know how saved!
Could you please help me with this questions, thanks in advance for your help & the library...
For configuring the Entity Framework event provider use the fluent API provided by Audit.EntityFramework.Configuration.Setup()
You can include the associations as follows:
Audit.EntityFramework.Configuration.Setup()
.ForAnyContext(config => config
.IncludeIndependantAssociations());
And about your sample code (what you should have included as textual code and not as an image):
The first line is not needed, since the UseEntityFramework() will
override the DataProvider
The primary key value can be calculated as: entity.TablePk = entry.PrimaryKey.FirstOrDefault().Value.ToString();

Keep two different versions of an entity in Doctrine ORM

I'm working on a Symfony4/Doctrine/MySQL project with the following requirement:
Users can create entities (say posts) that are visible in the public frontend only after approval by an admin
When a user edits his post after approval/publication, the changed post needs to be approved again before the changes will become visible in the frontend. But while approval is pending the old approved version of the post must remain visible in the frontend.
This means I have to keep two versions of every "Post" entity: the approved version for the frontend and the work-in-progress version for the backend.
In past projects with similar requirements I tried different approaches to this problem:
Using "Versionable behavior" (this was in the Symfony1/Propel days using sfPropelVersionableBehaviorPlugin). For display in the frontend, if an entity was not approved I had to fetch the previous versions until the latest approved version was found.
Using a second entity/database table "ApprovedPost" with the same field definition as the main "Post" entity. When a post is approved by the admin, it will be copied to the ApprovedPost table. The frontend operates on the ApprovedPost table only.
What is the current best practice to implement such a behavior?
Because I am chellenging this problem right now, I want to share my approach.
The entity is a request for something. Everytime something changes, the changes should be preserved.
The approach:
On every edit action, a new entity row is created.
The entity has an "approved" flag and a createdAt Date field.
A request has a nullable one-to-one self relation (to point to the root/parent entity).
A custom repository is used fo accessing the database.
The typical find and findAll methods are modified: they search for the most recent version (by the createdAt field) that is approved.
Search is done via custom SQL/DQL: (WHERE id = ?1 OR WHERE parent-id = ?1) AND WHERE approved = true SORT BY created_at DESC LIMIT 1
More features can be added like enabled/disabled, deletion and so on ...
If you want to render the page server side and show the changed or old versions, I would recommend writing e.g. a Twig extension. You could implement different search functions in the repo and handle the representaion via the extension (sorting, referencing ...).
I created an API, which is able to do both: return the newest version and return all versions (with or without root or newest), but I use the latter one in the frontend only if necessary.
Like dbrumann stated, this is a opinionated approach (I like custom repos, because I can create them type safe and I can decouple application from persistence logic).

Use FOSUserBundle in relation with yml-based Entities

I've started a Symfony2 project from scratch where I then installed FOSUserBundle.
Then, I have written (actually, generated with ORM Designer) some entities that need to have relations between them, and with the User entity.
I have Items belonging to Users, Collections belonging to Users that group Items, and so on.
Since I used FOSUserBundle I only have a basic User class (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md , step 3a) defined using annotations, no config/doctrine folder and no User.yml file in it.
I then created the MyBundle/Resources/config/doctrine folder and added the yml files mentioned above.
When I try to generate the entities with the command-line tool everything works fine: it will create the Entities from my yml files.
However, at this point, trying to load up in browsers the url where the login previously worked (when I only had the FOSUserBundle installed) will throw this error:
MappingException: No mapping file found named
'/var/www/concert/src/X/MyBundle/Resources/config/doctrine/User.orm.yml'
for class 'X\MyBundle\Entity\User'.
Following actions, such as generating the CRUD logic, will not work as long as I have an *.orm.yml file in the config/doctrine folder. If I remove those, CRUD generation will work, but generation of actual mysql tables won't.
Juggling with these gets me to a point where I can also get the tables, but then the actual app doesn't work if I try to use any of the url's where the newly generated CRUD is involved because since the entities are based on yml (which I remove to get things "working") it won't have any mapping knowledge.
Is this inherently wrong? To have yml-based entities in relationship with an User entity based on the FOSUserBundle and still be able to get the nice command-line generation tools?
The problem you describe stems from mixing configuration formats (yaml and I assume annotations). You can easily fix this by ditching the annotations in your models and replacing them with yaml-files like you would do in your own models.
Unfortunately the FOSUserBundle-docs only show you how to use annotations, so here is a quick transformation into yaml format when your X\MyBundle\Entity\User extends FOSUSerBundle's UserEntity:
X\MyBundle\Entity\User:
type: entity
table: fos_user
id:
id:
type: integer
strategy: { generator: "AUTO" }
The remaining stuff is taken care of by FOSUserBundle, as the BaseModel is a mapped-superclass and already describes the stuff in the User.orm.xml, but you could just as well replace the existing values or add additional values just like you would do with your own models.
If you don't use annotations throughout your app, you might also want to disable them in your app/config/config.yml to prevent side effects.

Generic comment system in Symfony2

I have in my Symfony 2.1 RC app a simple Comment model (using Doctrine 2). Every comment has a user and a message.
Currently, the CommentBundle manages comments on articles. I'd like it to be more generic to be able to comment any kind of entity without copying code across different bundles dedicated to comments...
For this to work, I also need a way to reference any entity from the comment one. I think having two fields entity_type and entity_id can be a nice solution. However, I can't get the object from these without mapping entity_type to classes manually and using the find method.
So how do I reference an entity from a comment ? And how can I create generic behavior working on several entities ?
You can create a abstract base class entity called Commentable and create entities that inherit Commentable such as Document or Post.
Since Document and Post are derived from Commentable, you can create a one to many relationship between the entities Commentable and Comment respectively.
Make sure to include in your base class ORM annotations for inheritance:
#InheritanceType
#DiscriminatorColumn
#DiscriminatorMap
Examples can be found on Doctrine Project Inheritance Documentation

Shared PKs and ObjectContext errors

I am using EF 4.3 in an ASP.NET WebForms application. I've started with model first approach with context object of type ObjectContext and POCO code generator (via T4).
At the beginning the Context was created at the beginning of every service method. While working on performance I decided to switch to context per web request. Unfortunately I have encountered an issue with Table-per-Type inheritance. I have two entities: Offer and OfferEdit. They are in a one to one relationship, and both share the same primary key. Basically an OfferEdit (OfferEdits table) is created once an Offer is being edited.
I query the context for a particular Offer entity more then once during web request. The error I get trying to execute:
var offer = Context.Offer.Where(o => o.Id == offerId).FirstOrDefault()
when this offer is already loaded to Context.Offer.EntitySet is
All objects in the EntitySet 'RuchEntities.Offer' must have unique primary keys.
However, an instance of type 'Ruch.Data.Model.OfferEdit' and an instance of type'Ruch.Data.Model.Offer' both have the same primary key
value,'EntitySet=Offer;Id=4139'.
Will appreciate all advice.
Sounds like you are misusing TPT inheritance. To make it clear EF inheritance works exactly same way as in .NET - the entity can be either of type Offer or OfferEdit. You can convert OfferEdit to Offer but it is still OfferEdit. It can never be of both types which means you can never have Offer entity with Id same as OfferEdit entity because same key cannot be used by two entity instances. You also never can change instance of Offer to OfferEdit because .NET doesn't allow you changing type of existing instance.

Resources